[Fusionforge-commits] FusionForge branch feature-plugin-repositoryapi-6.0 created. v6.0.5-29-g01b049d

Roland Mas lolando at libremir.placard.fr.eu.org
Tue Jan 10 10:04:03 CET 2017


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "FusionForge".

The branch, feature-plugin-repositoryapi-6.0 has been created
        at  01b049dbb13e66869bee9d9abb13fac61cb16a4a (commit)

- Log -----------------------------------------------------------------
https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=01b049dbb13e66869bee9d9abb13fac61cb16a4a

commit 01b049dbb13e66869bee9d9abb13fac61cb16a4a
Author: Roland Mas <lolando at debian.org>
Date:   Mon Jan 9 15:42:52 2017 +0100

    Updated testsuite after cronjob move

diff --git a/tests/func/60_PluginsRepositoryAPI/repositoryapiTest.php b/tests/func/60_PluginsRepositoryAPI/repositoryapiTest.php
index 9c7e73f..dc8f3e2 100644
--- a/tests/func/60_PluginsRepositoryAPI/repositoryapiTest.php
+++ b/tests/func/60_PluginsRepositoryAPI/repositoryapiTest.php
@@ -139,7 +139,7 @@ class RepositoryAPI extends FForge_SeleniumTestCase
 
 
 		// Collect activities
-		$this->cron("scm/parse_scm_repo_activities.php");
+		$this->cron_for_plugin("parse_scm_repo_activities.php", "repositoryapi");
 
 
 		// Check SOAP

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=420455ea06688f03e6e0bf5daea50ebe83da0faa

commit 420455ea06688f03e6e0bf5daea50ebe83da0faa
Author: Roland Mas <lolando at debian.org>
Date:   Mon Jan 9 15:09:56 2017 +0100

    Also moved database change for repositoryapi into the plugin

diff --git a/src/db/20161220-repository-activities.sql b/src/plugins/repositoryapi/db/repositoryapi-init.sql
similarity index 100%
rename from src/db/20161220-repository-activities.sql
rename to src/plugins/repositoryapi/db/repositoryapi-init.sql

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=5ac89c9bb17c456c30a8db1e7b29540acb6a3dcb

commit 5ac89c9bb17c456c30a8db1e7b29540acb6a3dcb
Author: Roland Mas <lolando at debian.org>
Date:   Mon Jan 9 15:05:38 2017 +0100

    Moved cronjob for repositoryapi into the plugin

diff --git a/src/etc/cron.d/fusionforge-scm b/src/etc/cron.d/fusionforge-scm
index 3140532..332aa46 100644
--- a/src/etc/cron.d/fusionforge-scm
+++ b/src/etc/cron.d/fusionforge-scm
@@ -8,6 +8,3 @@ PATH=@bindir@:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
 
 # Generate snapshots and tarballs from SCM repositories
 0 3 * * * root forge_run_job scm/generate_scm_snapshots.php
-
-# Gather activities from SCM repositories
-0 */3 * * * root forge_run_job scm/parse_scm_repo_activities.php
diff --git a/src/cronjobs/scm/parse_scm_repo_activities.php b/src/plugins/repositoryapi/cronjobs/parse_scm_repo_activities.php
similarity index 95%
rename from src/cronjobs/scm/parse_scm_repo_activities.php
rename to src/plugins/repositoryapi/cronjobs/parse_scm_repo_activities.php
index b97f29f..2063e88 100755
--- a/src/cronjobs/scm/parse_scm_repo_activities.php
+++ b/src/plugins/repositoryapi/cronjobs/parse_scm_repo_activities.php
@@ -21,7 +21,7 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-require (dirname(__FILE__).'/../../common/include/env.inc.php');
+require (dirname(__FILE__).'/../../../common/include/env.inc.php');
 require_once $gfcommon.'include/pre.php';
 require_once $gfcommon.'include/cron_utils.php';
 
diff --git a/src/plugins/repositoryapi/etc/cron.d/fusionforge-plugin-repositoryapi b/src/plugins/repositoryapi/etc/cron.d/fusionforge-plugin-repositoryapi
new file mode 100644
index 0000000..c0fdc62
--- /dev/null
+++ b/src/plugins/repositoryapi/etc/cron.d/fusionforge-plugin-repositoryapi
@@ -0,0 +1,2 @@
+# Gather activities from SCM repositories
+0 */3 * * * root forge_run_job scm/parse_scm_repo_activities.php

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=aa410265d0bfa2981220302fa27b96b072b97ac6

commit aa410265d0bfa2981220302fa27b96b072b97ac6
Author: Roland Mas <lolando at debian.org>
Date:   Mon Jan 9 10:57:42 2017 +0100

    Added type field to activity record (hardcoded "change" for now)

diff --git a/src/plugins/repositoryapi/include/repositoryapiPlugin.class.php b/src/plugins/repositoryapi/include/repositoryapiPlugin.class.php
index ee98552..db81347 100644
--- a/src/plugins/repositoryapi/include/repositoryapiPlugin.class.php
+++ b/src/plugins/repositoryapi/include/repositoryapiPlugin.class.php
@@ -85,6 +85,7 @@ class repositoryapiPlugin extends Plugin {
 				'group_id' => array('name'=>'group_id', 'type' => 'xsd:int'),
 				'repository_id' => array('name'=>'repository_id', 'type' => 'xsd:string'),
 				'timestamp' => array('name'=>'timestamp', 'type' => 'xsd:int'),
+				'type' => array('name'=>'type', 'type' => 'xsd:string'),
 				)
 			);
 
@@ -188,7 +189,8 @@ function &repositoryapi_repositoryActivity($session_ser, $t0, $t1, $limit=0, $of
 	}
 
 	$results = array();
-	$res = db_query_params("SELECT tstamp, repository_id, group_id FROM scm_activities WHERE tstamp BETWEEN $1 AND $2 ORDER BY tstamp, group_id, repository_id",
+	// "type" is "change" only so far, but extensible for the future
+	$res = db_query_params("SELECT tstamp, repository_id, group_id, 'change' AS type FROM scm_activities WHERE tstamp BETWEEN $1 AND $2 ORDER BY tstamp, group_id, repository_id",
 						   array($t0,
 								 $t1,
 							   ));
@@ -201,7 +203,8 @@ function &repositoryapi_repositoryActivity($session_ser, $t0, $t1, $limit=0, $of
 		if ($skipped >= $offset) {
 			$results[] = array('timestamp' => $arr['tstamp'],
 							   'repository_id' => $arr['repository_id'],
-							   'group_id' => $arr['group_id']);
+							   'group_id' => $arr['group_id'],
+							   'type' => $arr['type']);
 		} else {
 			$skipped = $skipped + 1;
 		}

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=1edfb4b1b59404683d1f5dfd01f60a5427414246

commit 1edfb4b1b59404683d1f5dfd01f60a5427414246
Author: Roland Mas <lolando at debian.org>
Date:   Mon Jan 9 10:55:00 2017 +0100

    Renamed plugin to repositoryapi for neutrality

diff --git a/autoinstall/install-src.sh b/autoinstall/install-src.sh
index 63f10a7..42d8c40 100755
--- a/autoinstall/install-src.sh
+++ b/autoinstall/install-src.sh
@@ -57,6 +57,6 @@ fi
         install-plugin-scmcvs install-plugin-scmsvn install-plugin-scmgit \
         install-plugin-blocks install-plugin-moinmoin \
         install-plugin-online_help install-plugin-taskboard install-plugin-message \
-	install-plugin-softwareheritage
+	install-plugin-repositoryapi
     make post-install
 )
diff --git a/autoinstall/install.sh b/autoinstall/install.sh
index 205e895..4b6d01b 100755
--- a/autoinstall/install.sh
+++ b/autoinstall/install.sh
@@ -43,8 +43,7 @@ if [ -e /etc/debian_version ]; then
 	    fusionforge-plugin-scmcvs fusionforge-plugin-scmsvn fusionforge-plugin-scmgit fusionforge-plugin-scmbzr \
 	    fusionforge-plugin-moinmoin \
 	    fusionforge-plugin-blocks fusionforge-plugin-taskboard \
-	    fusionforge-plugin-message fusionforge-plugin-softwareheritage
-	    fusionforge-plugin-message
+	    fusionforge-plugin-message fusionforge-plugin-repositoryapi
 	$APT install dpkg-dev
 	if ! dpkg-vendor --is Ubuntu; then
 	    apt-get install locales-all  # https://bugs.launchpad.net/ubuntu/+source/glibc/+bug/1394929
@@ -60,6 +59,6 @@ else
 	yum --enablerepo=epel install -y fusionforge fusionforge-shell fusionforge-scm \
 	    fusionforge-plugin-scmcvs fusionforge-plugin-scmsvn fusionforge-plugin-scmgit \
 	    fusionforge-plugin-blocks fusionforge-plugin-online_help fusionforge-plugin-taskboard \
-	    fusionforge-plugin-message fusionforge-plugin-globalactivity
+	    fusionforge-plugin-message fusionforge-plugin-repositoryapi
     fi
 fi
diff --git a/src/debian/plugins b/src/debian/plugins
index b637241..3c6fe27 100644
--- a/src/debian/plugins
+++ b/src/debian/plugins
@@ -88,7 +88,7 @@ Depends:
 Package: fusionforge-plugin-scmhook
 Depends: php-cli | php5-cli, php-curl | php5-curl, mksh, ${perl:Depends}
 
-Package: fusionforge-plugin-softwareheritage
+Package: fusionforge-plugin-repositoryapi
 Depends:
 
 Package: fusionforge-plugin-sysauthldap
diff --git a/src/plugins/softwareheritage/INSTALL b/src/plugins/repositoryapi/INSTALL
similarity index 55%
rename from src/plugins/softwareheritage/INSTALL
rename to src/plugins/repositoryapi/INSTALL
index f8930d7..067f4d0 100644
--- a/src/plugins/softwareheritage/INSTALL
+++ b/src/plugins/repositoryapi/INSTALL
@@ -1,7 +1,7 @@
-0. INSTALLATION of Softwareheritage Plugin
+0. INSTALLATION of Repository API Plugin
 
 i.e. : if the directory where the plugins are is  /srv/www/gforge/plugins you should end up 
-	with /srv/www/gforge/plugins/softwareheritage and all the files in it
+	with /srv/www/gforge/plugins/repositoryapi and all the files in it
 
 1. CONFIGURATION
 
@@ -9,8 +9,8 @@ A) Make the symbolic links for each section
 
 (this is just an example, you should change the variables for what you have on your installation)
 
-/$GFORGEDIR/www/plugins/softwareheritage -> /$GFORGEPLUGINSDIR/softwareheritage/www
-/$ETC/gforge ->  /$GFORGEPLUGINSDIR/softwareheritage/etc/plugins/softwareheritage
+/$GFORGEDIR/www/plugins/repositoryapi -> /$GFORGEPLUGINSDIR/repositoryapi/www
+/$ETC/gforge ->  /$GFORGEPLUGINSDIR/repositoryapi/etc/plugins/repositoryapi
 
 B) Run the configure-existing-git-repos.sh script to enable reflogs in existing Git repositories
 
diff --git a/src/plugins/repositoryapi/README b/src/plugins/repositoryapi/README
new file mode 100644
index 0000000..f4522e8
--- /dev/null
+++ b/src/plugins/repositoryapi/README
@@ -0,0 +1 @@
+Repository API plugin
\ No newline at end of file
diff --git a/src/plugins/softwareheritage/bin/configure-existing-git-repos.sh b/src/plugins/repositoryapi/bin/configure-existing-git-repos.sh
similarity index 100%
rename from src/plugins/softwareheritage/bin/configure-existing-git-repos.sh
rename to src/plugins/repositoryapi/bin/configure-existing-git-repos.sh
diff --git a/src/plugins/softwareheritage/common/softwareheritage-init.php b/src/plugins/repositoryapi/common/repositoryapi-init.php
similarity index 81%
rename from src/plugins/softwareheritage/common/softwareheritage-init.php
rename to src/plugins/repositoryapi/common/repositoryapi-init.php
index d38dc79..048dafc 100644
--- a/src/plugins/softwareheritage/common/softwareheritage-init.php
+++ b/src/plugins/repositoryapi/common/repositoryapi-init.php
@@ -20,11 +20,11 @@
  */
 
 global $gfplugins;
-require_once $gfplugins.'softwareheritage/include/softwareheritagePlugin.class.php' ;
+require_once $gfplugins.'repositoryapi/include/repositoryapiPlugin.class.php' ;
 
-$softwareheritagePluginObject = new softwareheritagePlugin ;
+$repositoryapiPluginObject = new repositoryapiPlugin ;
 
-register_plugin ($softwareheritagePluginObject) ;
+register_plugin ($repositoryapiPluginObject) ;
 
 // Local Variables:
 // mode: php
diff --git a/src/plugins/softwareheritage/etc/softwareheritage.ini b/src/plugins/repositoryapi/etc/repositoryapi.ini
similarity index 91%
rename from src/plugins/softwareheritage/etc/softwareheritage.ini
rename to src/plugins/repositoryapi/etc/repositoryapi.ini
index 74f2636..6c68bc3 100644
--- a/src/plugins/softwareheritage/etc/softwareheritage.ini
+++ b/src/plugins/repositoryapi/etc/repositoryapi.ini
@@ -1,4 +1,4 @@
-[softwareheritage]
+[repositoryapi]
 
 ; plugin_status is a string.
 ; valid means : production ready.
diff --git a/src/plugins/softwareheritage/include/SoftwareheritagePluginDescriptor.class.php b/src/plugins/repositoryapi/include/RepositoryAPIPluginDescriptor.class.php
similarity index 80%
rename from src/plugins/softwareheritage/include/SoftwareheritagePluginDescriptor.class.php
rename to src/plugins/repositoryapi/include/RepositoryAPIPluginDescriptor.class.php
index 2d8c51a..3c45ba3 100644
--- a/src/plugins/softwareheritage/include/SoftwareheritagePluginDescriptor.class.php
+++ b/src/plugins/repositoryapi/include/RepositoryAPIPluginDescriptor.class.php
@@ -23,9 +23,9 @@
 
 require_once 'common/plugin/PluginDescriptor.class.php';
 
-class SoftwareheritagePluginDescriptor extends PluginDescriptor {
+class RepositoryAPIPluginDescriptor extends PluginDescriptor {
 
-    function SoftwareheritagePluginDescriptor() {
-        $this->PluginDescriptor(_('Softwareheritage'), 'v1.0', _('Metadata retrieval API for Software Heritage'));
+    function RepositoryAPIPluginDescriptor() {
+        $this->PluginDescriptor(_('RepositoryAPI'), 'v1.0', _('Metadata retrieval API for repositories'));
     }
 }
diff --git a/src/plugins/softwareheritage/include/SoftwareheritagePluginInfo.class.php b/src/plugins/repositoryapi/include/RepositoryAPIPluginInfo.class.php
similarity index 79%
rename from src/plugins/softwareheritage/include/SoftwareheritagePluginInfo.class.php
rename to src/plugins/repositoryapi/include/RepositoryAPIPluginInfo.class.php
index ff3c512..111285a 100644
--- a/src/plugins/softwareheritage/include/SoftwareheritagePluginInfo.class.php
+++ b/src/plugins/repositoryapi/include/RepositoryAPIPluginInfo.class.php
@@ -21,13 +21,13 @@
  * Copyright 2011 (c) France Telecom, Coclico project
  */
 require_once 'common/plugin/PluginInfo.class.php';
-require_once 'SoftwareheritagePluginDescriptor.class.php';
+require_once 'RepositoryAPIPluginDescriptor.class.php';
 
-class SoftwareheritagePluginInfo extends PluginInfo {
+class RepositoryAPIPluginInfo extends PluginInfo {
 
-    function SoftwareheritagePluginInfo(&$plugin) {
+    function RepositoryAPIPluginInfo(&$plugin) {
         $this->PluginInfo($plugin);
-        $this->setPluginDescriptor(new SoftwareheritagePluginDescriptor());
+        $this->setPluginDescriptor(new RepositoryAPIPluginDescriptor());
     }
 
 }
diff --git a/src/plugins/softwareheritage/include/softwareheritagePlugin.class.php b/src/plugins/repositoryapi/include/repositoryapiPlugin.class.php
similarity index 75%
rename from src/plugins/softwareheritage/include/softwareheritagePlugin.class.php
rename to src/plugins/repositoryapi/include/repositoryapiPlugin.class.php
index a6636ed..ee98552 100644
--- a/src/plugins/softwareheritage/include/softwareheritagePlugin.class.php
+++ b/src/plugins/repositoryapi/include/repositoryapiPlugin.class.php
@@ -1,7 +1,7 @@
 <?php
 
 /**
- * softwareheritagePlugin Class
+ * repositoryapiPlugin Class
  *
  *
  * This file is part of FusionForge.
@@ -21,11 +21,11 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-class softwareheritagePlugin extends Plugin {
+class repositoryapiPlugin extends Plugin {
 	public function __construct($id=0) {
 		$this->Plugin($id) ;
-		$this->name = "softwareheritage";
-		$this->text = "Software Heritage"; // To show in the tabs, use...
+		$this->name = "repositoryapi";
+		$this->text = "Repository API"; // To show in the tabs, use...
 		$this->_addHook('register_soap');
 	}
 
@@ -34,7 +34,7 @@ class softwareheritagePlugin extends Plugin {
 		$uri = 'http://'.forge_get_config('web_host');
 
 		$server->wsdl->addComplexType(
-			'SoftwareheritageRepositoryInfo',
+			'RepositoryAPIRepositoryInfo',
 			'complexType',
 			'struct',
 			'sequence',
@@ -48,35 +48,35 @@ class softwareheritagePlugin extends Plugin {
 			);
 
 		$server->wsdl->addComplexType(
-			'ArrayOfSoftwareheritageRepositoryInfo',
+			'ArrayOfRepositoryAPIRepositoryInfo',
 			'complexType',
 			'array',
 			'',
 			'SOAP-ENC:Array',
 			array(),
-			array(array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'tns:SoftwareheritageRepositoryInfo[]')),
-			'tns:SoftwareheritageRepositoryInfo');
+			array(array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'tns:RepositoryAPIRepositoryInfo[]')),
+			'tns:RepositoryAPIRepositoryInfo');
                
 		$server->register(
-			'softwareheritage_repositoryList',
+			'repositoryapi_repositoryList',
 			array('session_ser'=>'xsd:string',
 				  'limit'=>'xsd:int',
 				  'offset'=>'xsd:int',
 				),
-			array('return'=>'tns:ArrayOfSoftwareheritageRepositoryInfo'),
+			array('return'=>'tns:ArrayOfRepositoryAPIRepositoryInfo'),
 			$uri,
-                       $uri.'#softwareheritage_repositoryList','rpc','encoded');
+                       $uri.'#repositoryapi_repositoryList','rpc','encoded');
 
 		$server->register(
-			'softwareheritage_repositoryInfo',
+			'repositoryapi_repositoryInfo',
 			array('session_ser'=>'xsd:string',
 				'repository_id'=>'xsd:string'),
-			array('return'=>'tns:SoftwareheritageRepositoryInfo'),
+			array('return'=>'tns:RepositoryAPIRepositoryInfo'),
 			$uri,
-                       $uri.'#softwareheritage_repositoryInfo','rpc','encoded');
+                       $uri.'#repositoryapi_repositoryInfo','rpc','encoded');
 
 		$server->wsdl->addComplexType(
-			'SoftwareheritageActivity',
+			'RepositoryAPIActivity',
 			'complexType',
 			'struct',
 			'sequence',
@@ -89,33 +89,33 @@ class softwareheritagePlugin extends Plugin {
 			);
 
 		$server->wsdl->addComplexType(
-			'ArrayOfSoftwareheritageActivity',
+			'ArrayOfRepositoryAPIActivity',
 			'complexType',
 			'array',
 			'',
 			'SOAP-ENC:Array',
 			array(),
-			array(array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'tns:SoftwareheritageActivity[]')),
-			'tns:SoftwareheritageActivity');
+			array(array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'tns:RepositoryAPIActivity[]')),
+			'tns:RepositoryAPIActivity');
                
 		$server->register(
-			'softwareheritage_repositoryActivity',
+			'repositoryapi_repositoryActivity',
 			array('session_ser'=>'xsd:string',
 				  't0'=>'xsd:int',
 				  't1'=>'xsd:int',
 				  'limit'=>'xsd:int',
 				  'offset'=>'xsd:int',
 				),
-			array('return'=>'tns:ArrayOfSoftwareheritageActivity'),
+			array('return'=>'tns:ArrayOfRepositoryAPIActivity'),
 			$uri,
-                       $uri.'#softwareheritage_repositoryActivity','rpc','encoded');
+                       $uri.'#repositoryapi_repositoryActivity','rpc','encoded');
 
 	}
 
 
 }
 
-function &softwareheritage_repositoryList($session_ser, $limit=0, $offset=0) {
+function &repositoryapi_repositoryList($session_ser, $limit=0, $offset=0) {
 	continue_session($session_ser);
 
 	$maxnum = 1000;
@@ -153,7 +153,7 @@ function &softwareheritage_repositoryList($session_ser, $limit=0, $offset=0) {
 	return $res2;
 }
 
-function &softwareheritage_repositoryInfo($session_ser, $repository_id) {
+function &repositoryapi_repositoryInfo($session_ser, $repository_id) {
 	continue_session($session_ser);
 
 	$params = array();
@@ -163,14 +163,14 @@ function &softwareheritage_repositoryInfo($session_ser, $repository_id) {
 	plugin_hook('get_scm_repo_info',$params);
 
 	if ($params['results'] == NULL) {
-		$sf = new soap_fault('','softwareheritage_repositoryInfo',_('Error when fetching repository info'),_('Error when fetching repository info'));
+		$sf = new soap_fault('','repositoryapi_repositoryInfo',_('Error when fetching repository info'),_('Error when fetching repository info'));
 		return $sf;
 	}
 
 	return $params['results'];
 }
 
-function &softwareheritage_repositoryActivity($session_ser, $t0, $t1, $limit=0, $offset=0) {
+function &repositoryapi_repositoryActivity($session_ser, $t0, $t1, $limit=0, $offset=0) {
 	continue_session($session_ser);
 
 	if ($t1 < $t0) {
diff --git a/src/plugins/softwareheritage/README b/src/plugins/softwareheritage/README
deleted file mode 100644
index 96617ee..0000000
--- a/src/plugins/softwareheritage/README
+++ /dev/null
@@ -1 +0,0 @@
-Software Heritage plugin
\ No newline at end of file
diff --git a/tests/func/60_PluginsSoftwareHeritage/softwareheritageTest.php b/tests/func/60_PluginsRepositoryAPI/repositoryapiTest.php
similarity index 90%
rename from tests/func/60_PluginsSoftwareHeritage/softwareheritageTest.php
rename to tests/func/60_PluginsRepositoryAPI/repositoryapiTest.php
index 8718769..9c7e73f 100644
--- a/tests/func/60_PluginsSoftwareHeritage/softwareheritageTest.php
+++ b/tests/func/60_PluginsRepositoryAPI/repositoryapiTest.php
@@ -23,15 +23,15 @@
 
 require_once dirname(dirname(__FILE__)).'/SeleniumForge.php';
 
-class SoftwareHeritage extends FForge_SeleniumTestCase
+class RepositoryAPI extends FForge_SeleniumTestCase
 {
 	public $fixture = 'projecta';
 
-	function testSoftwareHeritage()
+	function testRepositoryAPI()
 	{
 		$this->loadAndCacheFixture();
 
-		$this->activatePlugin('softwareheritage');
+		$this->activatePlugin('repositoryapi');
 		$this->activatePlugin('scmgit');
 
 		$this->open(ROOT);
@@ -156,7 +156,7 @@ class SoftwareHeritage extends FForge_SeleniumTestCase
 		$this->assertNotEquals($session,"");
 
 		// Get repository list as admin
-		$response = $soapclient->softwareheritage_repositoryList($session,100,0);
+		$response = $soapclient->repositoryapi_repositoryList($session,100,0);
 		$repos = array();
 		foreach ($response as $data) {
 			$repos[$data->repository_id] = $data;
@@ -170,7 +170,7 @@ class SoftwareHeritage extends FForge_SeleniumTestCase
 		$this->assertEquals(4,count($repos['projectb/svn/projectb']->repository_urls));
 
 		// Get repository list as anonymous
-		$response = $soapclient->softwareheritage_repositoryList('',100,0);
+		$response = $soapclient->repositoryapi_repositoryList('',100,0);
 		$repos = array();
 		foreach ($response as $data) {
 			$repos[$data->repository_id] = $data;
@@ -184,28 +184,28 @@ class SoftwareHeritage extends FForge_SeleniumTestCase
 		$this->assertEquals(2,count($repos['projectb/svn/projectb']->repository_urls));
 
 		// Get repository info as admin
-		$response = $soapclient->softwareheritage_repositoryInfo($session,'projecta/git/projecta');
+		$response = $soapclient->repositoryapi_repositoryInfo($session,'projecta/git/projecta');
 		$this->assertNotEquals(NULL,$response);
 		$this->assertEquals(3,count($response->repository_urls));
 		
-		$response = $soapclient->softwareheritage_repositoryInfo($session,'projectb/svn/projectb');
+		$response = $soapclient->repositoryapi_repositoryInfo($session,'projectb/svn/projectb');
 		$this->assertNotEquals(NULL,$response);
 		$this->assertEquals(4,count($response->repository_urls));
 
 		// Get activities for repositories		
-		$response = $soapclient->softwareheritage_repositoryActivity($session,$t0,time(),0,0);
+		$response = $soapclient->repositoryapi_repositoryActivity($session,$t0,time(),0,0);
 		$this->assertNotEquals(NULL,$response);
 		$this->assertEquals(5,count($response));
 		// Check limit/offset
-		$response = $soapclient->softwareheritage_repositoryActivity($session,$t0,time(),2,0);
+		$response = $soapclient->repositoryapi_repositoryActivity($session,$t0,time(),2,0);
 		$this->assertNotEquals(NULL,$response);
 		$this->assertEquals(2,count($response));
-		$response = $soapclient->softwareheritage_repositoryActivity($session,$t0,time(),0,2);
+		$response = $soapclient->repositoryapi_repositoryActivity($session,$t0,time(),0,2);
 		$this->assertNotEquals(NULL,$response);
 		$this->assertEquals(3,count($response));
 		// Check time range
 		sleep(15);
-		$response = $soapclient->softwareheritage_repositoryActivity($session,time()-10,time(),0,0);
+		$response = $soapclient->repositoryapi_repositoryActivity($session,time()-10,time(),0,0);
 		$this->assertNotEquals(NULL,$response);
 		$this->assertEquals(0,count($response));
 	}

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=2e4995e1cbfd579c597efb9c4c57f112588cfd1e

commit 2e4995e1cbfd579c597efb9c4c57f112588cfd1e
Author: Roland Mas <lolando at debian.org>
Date:   Mon Jan 2 12:45:49 2017 +0100

    Fixes to pagination code

diff --git a/src/plugins/softwareheritage/include/softwareheritagePlugin.class.php b/src/plugins/softwareheritage/include/softwareheritagePlugin.class.php
index a93a5c7..a6636ed 100644
--- a/src/plugins/softwareheritage/include/softwareheritagePlugin.class.php
+++ b/src/plugins/softwareheritage/include/softwareheritagePlugin.class.php
@@ -136,16 +136,14 @@ function &softwareheritage_repositoryList($session_ser, $limit=0, $offset=0) {
 	}
 	$res = $res2;
 
-	$counter = 0;
 	$skipped = 0;
 	$res2 = array();
 	foreach ($res as $r) {
-		if ($counter >= $limit) {
+		if (count($res2) >= $limit) {
 			break;
 		}
 		if ($skipped >= $offset) {
 			$res2[] = $r;
-			$counter = $counter + 1;
 		} else {
 			$skipped = $skipped + 1;
 		}
@@ -194,21 +192,18 @@ function &softwareheritage_repositoryActivity($session_ser, $t0, $t1, $limit=0,
 						   array($t0,
 								 $t1,
 							   ));
-	$counter = 0;
 	$skipped = 0;
-	while ($arr = db_fetch_array($res)) {
-		if ($counter >= $limit) {
-			break;
+	while ((count($results) < $limit) && ($arr = db_fetch_array($res))) {
+		if (!forge_check_perm('scm',$arr['group_id'],'read')) {
+			continue;
 		}
-		if (forge_check_perm('scm',$arr['group_id'],'read')) {
-			if ($skipped >= $offset) {
-				$results[] = array('timestamp' => $arr['tstamp'],
-								   'repository_id' => $arr['repository_id'],
-								   'group_id' => $arr['group_id']);
-				$counter = $counter + 1;
-			} else {
-				$skipped = $skipped + 1;
-			}
+
+		if ($skipped >= $offset) {
+			$results[] = array('timestamp' => $arr['tstamp'],
+							   'repository_id' => $arr['repository_id'],
+							   'group_id' => $arr['group_id']);
+		} else {
+			$skipped = $skipped + 1;
 		}
 	}
 

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=f8dbb519862f7f2a5552d7a385a3ec8e41a22207

commit f8dbb519862f7f2a5552d7a385a3ec8e41a22207
Author: Roland Mas <lolando at debian.org>
Date:   Mon Jan 2 12:04:15 2017 +0100

    Pagination for softwareheritage_repositoryList()

diff --git a/src/plugins/softwareheritage/include/softwareheritagePlugin.class.php b/src/plugins/softwareheritage/include/softwareheritagePlugin.class.php
index 8f3884e..a93a5c7 100644
--- a/src/plugins/softwareheritage/include/softwareheritagePlugin.class.php
+++ b/src/plugins/softwareheritage/include/softwareheritagePlugin.class.php
@@ -59,7 +59,10 @@ class softwareheritagePlugin extends Plugin {
                
 		$server->register(
 			'softwareheritage_repositoryList',
-			array('session_ser'=>'xsd:string'),
+			array('session_ser'=>'xsd:string',
+				  'limit'=>'xsd:int',
+				  'offset'=>'xsd:int',
+				),
 			array('return'=>'tns:ArrayOfSoftwareheritageRepositoryInfo'),
 			$uri,
                        $uri.'#softwareheritage_repositoryList','rpc','encoded');
@@ -112,9 +115,14 @@ class softwareheritagePlugin extends Plugin {
 
 }
 
-function &softwareheritage_repositoryList($session_ser) {
+function &softwareheritage_repositoryList($session_ser, $limit=0, $offset=0) {
 	continue_session($session_ser);
 
+	$maxnum = 1000;
+	if ($limit > $maxnum || $limit <= 0) {
+		$limit = $maxnum;
+	}
+
 	$params = array();
 	$results = array();
 	$params['results'] = &$results;
@@ -126,6 +134,23 @@ function &softwareheritage_repositoryList($session_ser) {
 			$res2[] = $res;
 		}
 	}
+	$res = $res2;
+
+	$counter = 0;
+	$skipped = 0;
+	$res2 = array();
+	foreach ($res as $r) {
+		if ($counter >= $limit) {
+			break;
+		}
+		if ($skipped >= $offset) {
+			$res2[] = $r;
+			$counter = $counter + 1;
+		} else {
+			$skipped = $skipped + 1;
+		}
+	}
+	$res = $res2;
 
 	return $res2;
 }
diff --git a/tests/func/60_PluginsSoftwareHeritage/softwareheritageTest.php b/tests/func/60_PluginsSoftwareHeritage/softwareheritageTest.php
index 788db6e..8718769 100644
--- a/tests/func/60_PluginsSoftwareHeritage/softwareheritageTest.php
+++ b/tests/func/60_PluginsSoftwareHeritage/softwareheritageTest.php
@@ -156,7 +156,7 @@ class SoftwareHeritage extends FForge_SeleniumTestCase
 		$this->assertNotEquals($session,"");
 
 		// Get repository list as admin
-		$response = $soapclient->softwareheritage_repositoryList($session);
+		$response = $soapclient->softwareheritage_repositoryList($session,100,0);
 		$repos = array();
 		foreach ($response as $data) {
 			$repos[$data->repository_id] = $data;
@@ -170,7 +170,7 @@ class SoftwareHeritage extends FForge_SeleniumTestCase
 		$this->assertEquals(4,count($repos['projectb/svn/projectb']->repository_urls));
 
 		// Get repository list as anonymous
-		$response = $soapclient->softwareheritage_repositoryList('');
+		$response = $soapclient->softwareheritage_repositoryList('',100,0);
 		$repos = array();
 		foreach ($response as $data) {
 			$repos[$data->repository_id] = $data;

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=19db130615d4dd3c66b019ab635410ce9784d8ac

commit 19db130615d4dd3c66b019ab635410ce9784d8ac
Author: Roland Mas <lolando at debian.org>
Date:   Mon Jan 2 11:57:02 2017 +0100

    Sort loading of plugins by plugin name for reproducibility

diff --git a/src/common/include/PluginManager.class.php b/src/common/include/PluginManager.class.php
index c5b72c5..8d68777 100644
--- a/src/common/include/PluginManager.class.php
+++ b/src/common/include/PluginManager.class.php
@@ -54,7 +54,7 @@ class PluginManager extends FFError {
 	 */
 	function GetPlugins() {
 		$this->plugins_data = array();
-		$res = db_query_params('SELECT plugin_id, plugin_name FROM plugins',
+		$res = db_query_params('SELECT plugin_id, plugin_name FROM plugins ORDER BY plugin_name',
 				array());
 		$rows = db_numrows($res);
 		for ($i=0; $i<$rows; $i++) {

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=9a59b6dafb5476d62cce4be6957208888a2169ff

commit 9a59b6dafb5476d62cce4be6957208888a2169ff
Author: Roland Mas <lolando at debian.org>
Date:   Mon Dec 26 11:32:13 2016 +0100

    Gather SCM activity every 3 hours instead of daily

diff --git a/src/etc/cron.d/fusionforge-scm b/src/etc/cron.d/fusionforge-scm
index 80f4256..3140532 100644
--- a/src/etc/cron.d/fusionforge-scm
+++ b/src/etc/cron.d/fusionforge-scm
@@ -10,4 +10,4 @@ PATH=@bindir@:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
 0 3 * * * root forge_run_job scm/generate_scm_snapshots.php
 
 # Gather activities from SCM repositories
-0 3 * * * root forge_run_job scm/parse_scm_repo_activities.php
+0 */3 * * * root forge_run_job scm/parse_scm_repo_activities.php

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=86f976976367150cbf37d2864cd7ce7e10594515

commit 86f976976367150cbf37d2864cd7ce7e10594515
Author: Roland Mas <lolando at debian.org>
Date:   Mon Dec 26 11:18:52 2016 +0100

    Fixes to repository reconf script

diff --git a/src/plugins/softwareheritage/bin/configure-existing-git-repos.sh b/src/plugins/softwareheritage/bin/configure-existing-git-repos.sh
index 56e0fe4..aa200c1 100755
--- a/src/plugins/softwareheritage/bin/configure-existing-git-repos.sh
+++ b/src/plugins/softwareheritage/bin/configure-existing-git-repos.sh
@@ -1,18 +1,11 @@
-#!/bin/bash -e
+#! /bin/sh
 
+set -e
 
-case "$1" in
-    configure)
-	repos_path=$(forge_get_config repos_path scmgit)
-	find $repos_path -path \*.git/config | while read i ; do
-	    p="${i%/config}"
-	    r=$(realpath "$p")
-	    GIT_DIR="$r" git config core.logAllRefUpdates true
-	done
-        ;;
-    remove)
-        ;;
-    *)
-        echo "Usage: $0 {configure|remove}"
-        exit 1
-esac
+repos_path=$(forge_get_config repos_path scmgit)
+cd "$repos_path"
+find -path \*.git/config | while read i ; do
+    p="${i%/config}"
+    r=$(realpath "$p")
+    GIT_DIR="$r" git config core.logAllRefUpdates true
+done

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=ddfd685c5d253457f8c7e4e95b47e1b71f59b108

commit ddfd685c5d253457f8c7e4e95b47e1b71f59b108
Author: Roland Mas <lolando at debian.org>
Date:   Mon Dec 26 10:50:41 2016 +0100

    Added script to configure Git repositories for reflogs

diff --git a/src/plugins/softwareheritage/INSTALL b/src/plugins/softwareheritage/INSTALL
index a3d0dc2..f8930d7 100644
--- a/src/plugins/softwareheritage/INSTALL
+++ b/src/plugins/softwareheritage/INSTALL
@@ -11,3 +11,6 @@ A) Make the symbolic links for each section
 
 /$GFORGEDIR/www/plugins/softwareheritage -> /$GFORGEPLUGINSDIR/softwareheritage/www
 /$ETC/gforge ->  /$GFORGEPLUGINSDIR/softwareheritage/etc/plugins/softwareheritage
+
+B) Run the configure-existing-git-repos.sh script to enable reflogs in existing Git repositories
+
diff --git a/src/plugins/softwareheritage/bin/configure-existing-git-repos.sh b/src/plugins/softwareheritage/bin/configure-existing-git-repos.sh
new file mode 100755
index 0000000..56e0fe4
--- /dev/null
+++ b/src/plugins/softwareheritage/bin/configure-existing-git-repos.sh
@@ -0,0 +1,18 @@
+#!/bin/bash -e
+
+
+case "$1" in
+    configure)
+	repos_path=$(forge_get_config repos_path scmgit)
+	find $repos_path -path \*.git/config | while read i ; do
+	    p="${i%/config}"
+	    r=$(realpath "$p")
+	    GIT_DIR="$r" git config core.logAllRefUpdates true
+	done
+        ;;
+    remove)
+        ;;
+    *)
+        echo "Usage: $0 {configure|remove}"
+        exit 1
+esac

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=946be73c8424b643cc00869dceaa0377d95b33ea

commit 946be73c8424b643cc00869dceaa0377d95b33ea
Author: Roland Mas <lolando at debian.org>
Date:   Wed Dec 21 10:53:07 2016 +0100

    Make test a little more resilient against race conditions

diff --git a/tests/func/60_PluginsSoftwareHeritage/softwareheritageTest.php b/tests/func/60_PluginsSoftwareHeritage/softwareheritageTest.php
index b715307..788db6e 100644
--- a/tests/func/60_PluginsSoftwareHeritage/softwareheritageTest.php
+++ b/tests/func/60_PluginsSoftwareHeritage/softwareheritageTest.php
@@ -61,7 +61,7 @@ class SoftwareHeritage extends FForge_SeleniumTestCase
 		// Run the cronjob to create repositories
 		$this->waitSystasks();
 
-		sleep(1);
+		sleep(2);
 		$t0 = time();
 
 		// Get the address of the Git repo

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=b69bcab4cc079989ab6bb36896915abfdb498b13

commit b69bcab4cc079989ab6bb36896915abfdb498b13
Author: Roland Mas <lolando at debian.org>
Date:   Wed Dec 21 10:14:26 2016 +0100

    Implement pagination for repositoryActivity (with test)

diff --git a/src/plugins/softwareheritage/include/softwareheritagePlugin.class.php b/src/plugins/softwareheritage/include/softwareheritagePlugin.class.php
index 2b68e25..8f3884e 100644
--- a/src/plugins/softwareheritage/include/softwareheritagePlugin.class.php
+++ b/src/plugins/softwareheritage/include/softwareheritagePlugin.class.php
@@ -99,7 +99,9 @@ class softwareheritagePlugin extends Plugin {
 			'softwareheritage_repositoryActivity',
 			array('session_ser'=>'xsd:string',
 				  't0'=>'xsd:int',
-				  't1'=>'xsd:int'
+				  't1'=>'xsd:int',
+				  'limit'=>'xsd:int',
+				  'offset'=>'xsd:int',
 				),
 			array('return'=>'tns:ArrayOfSoftwareheritageActivity'),
 			$uri,
@@ -145,7 +147,7 @@ function &softwareheritage_repositoryInfo($session_ser, $repository_id) {
 	return $params['results'];
 }
 
-function &softwareheritage_repositoryActivity($session_ser, $t0, $t1) {
+function &softwareheritage_repositoryActivity($session_ser, $t0, $t1, $limit=0, $offset=0) {
 	continue_session($session_ser);
 
 	if ($t1 < $t0) {
@@ -157,24 +159,35 @@ function &softwareheritage_repositoryActivity($session_ser, $t0, $t1) {
 	if ($t1 - $t0 > $maxspan) {
 		$t0 = $t1 - $maxspan;
 	}
+	$maxnum = 1000;
+	if ($limit > $maxnum || $limit <= 0) {
+		$limit = $maxnum;
+	}
 
 	$results = array();
 	$res = db_query_params("SELECT tstamp, repository_id, group_id FROM scm_activities WHERE tstamp BETWEEN $1 AND $2 ORDER BY tstamp, group_id, repository_id",
 						   array($t0,
-								 $t1));
+								 $t1,
+							   ));
+	$counter = 0;
+	$skipped = 0;
 	while ($arr = db_fetch_array($res)) {
-		$results[] = array('timestamp' => $arr['tstamp'],
-						   'repository_id' => $arr['repository_id'],
-						   'group_id' => $arr['group_id']);
-	}
-	$res2 = array();
-	foreach ($results as $res) {
-		if (forge_check_perm('scm',$res['group_id'],'read')) {
-			$res2[] = $res;
+		if ($counter >= $limit) {
+			break;
+		}
+		if (forge_check_perm('scm',$arr['group_id'],'read')) {
+			if ($skipped >= $offset) {
+				$results[] = array('timestamp' => $arr['tstamp'],
+								   'repository_id' => $arr['repository_id'],
+								   'group_id' => $arr['group_id']);
+				$counter = $counter + 1;
+			} else {
+				$skipped = $skipped + 1;
+			}
 		}
 	}
 
-	return $res2;
+	return $results;
 }
 
 // Local Variables:
diff --git a/tests/func/60_PluginsSoftwareHeritage/softwareheritageTest.php b/tests/func/60_PluginsSoftwareHeritage/softwareheritageTest.php
index 67f0adf..b715307 100644
--- a/tests/func/60_PluginsSoftwareHeritage/softwareheritageTest.php
+++ b/tests/func/60_PluginsSoftwareHeritage/softwareheritageTest.php
@@ -193,11 +193,19 @@ class SoftwareHeritage extends FForge_SeleniumTestCase
 		$this->assertEquals(4,count($response->repository_urls));
 
 		// Get activities for repositories		
-		$response = $soapclient->softwareheritage_repositoryActivity($session,$t0,time());
+		$response = $soapclient->softwareheritage_repositoryActivity($session,$t0,time(),0,0);
 		$this->assertNotEquals(NULL,$response);
 		$this->assertEquals(5,count($response));
+		// Check limit/offset
+		$response = $soapclient->softwareheritage_repositoryActivity($session,$t0,time(),2,0);
+		$this->assertNotEquals(NULL,$response);
+		$this->assertEquals(2,count($response));
+		$response = $soapclient->softwareheritage_repositoryActivity($session,$t0,time(),0,2);
+		$this->assertNotEquals(NULL,$response);
+		$this->assertEquals(3,count($response));
+		// Check time range
 		sleep(15);
-		$response = $soapclient->softwareheritage_repositoryActivity($session,time()-10,time());
+		$response = $soapclient->softwareheritage_repositoryActivity($session,time()-10,time(),0,0);
 		$this->assertNotEquals(NULL,$response);
 		$this->assertEquals(0,count($response));
 	}

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=02e3b27a6f1bb420f0c418d1e9c0679596828a65

commit 02e3b27a6f1bb420f0c418d1e9c0679596828a65
Author: Roland Mas <lolando at debian.org>
Date:   Tue Dec 20 13:17:05 2016 +0100

    Refactor a bit

diff --git a/src/common/include/SCMPlugin.class.php b/src/common/include/SCMPlugin.class.php
index 296e798..8cecf82 100644
--- a/src/common/include/SCMPlugin.class.php
+++ b/src/common/include/SCMPlugin.class.php
@@ -333,18 +333,6 @@ abstract class SCMPlugin extends Plugin {
 		return true;
 	}
 
-    function get_scm_repo_activity(&$params) {
-		$res = db_query_params("SELECT tstamp, repository_id, group_id FROM scm_activities WHERE plugin_id=$1 AND tstamp BETWEEN $2 AND $3 ORDER BY group_id, repository_id, tstamp",
-							   array($this->getID(),
-									 $params['t0'],
-									 $params['t1']));
-		while ($arr = db_fetch_array($res)) {
-			$params['results'][] = array('timestamp' => $arr['tstamp'],
-										 'repository_id' => $arr['repository_id'],
-										 'group_id' => $arr['group_id']);
-		}
-	}
-
 	function checkParams ($params) {
 		$group_id = $params['group_id'] ;
 		$project = group_get_object($group_id);
diff --git a/src/plugins/scmgit/common/GitPlugin.class.php b/src/plugins/scmgit/common/GitPlugin.class.php
index cbc835c..edff1a1 100644
--- a/src/plugins/scmgit/common/GitPlugin.class.php
+++ b/src/plugins/scmgit/common/GitPlugin.class.php
@@ -55,7 +55,6 @@ control over it to the project's administrator.");
 		$this->_addHook('scm_delete_repo');
 		$this->_addHook('get_scm_repo_list');
 		$this->_addHook('get_scm_repo_info');
-		$this->_addHook('get_scm_repo_activity');
 		$this->_addHook('parse_scm_repo_activities');
 		$this->_addHook('widget_instance', 'myPageBox', false);
 		$this->_addHook('widgets', 'widgets', false);
diff --git a/src/plugins/scmsvn/common/SVNPlugin.class.php b/src/plugins/scmsvn/common/SVNPlugin.class.php
index dc92643..5cfbb96 100644
--- a/src/plugins/scmsvn/common/SVNPlugin.class.php
+++ b/src/plugins/scmsvn/common/SVNPlugin.class.php
@@ -58,7 +58,6 @@ some control over it to the project's administrator.");
 		$this->_addHook('scm_gather_stats');
 		$this->_addHook('get_scm_repo_list');
 		$this->_addHook('get_scm_repo_info');
-		$this->_addHook('get_scm_repo_activity');
 		$this->_addHook('parse_scm_repo_activities');
 		$this->_addHook('activity');
 
diff --git a/src/plugins/softwareheritage/include/softwareheritagePlugin.class.php b/src/plugins/softwareheritage/include/softwareheritagePlugin.class.php
index e84071b..2b68e25 100644
--- a/src/plugins/softwareheritage/include/softwareheritagePlugin.class.php
+++ b/src/plugins/softwareheritage/include/softwareheritagePlugin.class.php
@@ -158,12 +158,15 @@ function &softwareheritage_repositoryActivity($session_ser, $t0, $t1) {
 		$t0 = $t1 - $maxspan;
 	}
 
-	$params = array('t0' => $t0,
-					't1' => $t1);
 	$results = array();
-	$params['results'] = &$results;
-	plugin_hook('get_scm_repo_activity',$params);
-
+	$res = db_query_params("SELECT tstamp, repository_id, group_id FROM scm_activities WHERE tstamp BETWEEN $1 AND $2 ORDER BY tstamp, group_id, repository_id",
+						   array($t0,
+								 $t1));
+	while ($arr = db_fetch_array($res)) {
+		$results[] = array('timestamp' => $arr['tstamp'],
+						   'repository_id' => $arr['repository_id'],
+						   'group_id' => $arr['group_id']);
+	}
 	$res2 = array();
 	foreach ($results as $res) {
 		if (forge_check_perm('scm',$res['group_id'],'read')) {

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=3071df7d1d45b8861b18d1bdc6e509e727278111

commit 3071df7d1d45b8861b18d1bdc6e509e727278111
Author: Roland Mas <lolando at debian.org>
Date:   Tue Dec 20 13:02:28 2016 +0100

    Restrict maximum span for SCM activities

diff --git a/src/plugins/softwareheritage/include/softwareheritagePlugin.class.php b/src/plugins/softwareheritage/include/softwareheritagePlugin.class.php
index e2646ea..e84071b 100644
--- a/src/plugins/softwareheritage/include/softwareheritagePlugin.class.php
+++ b/src/plugins/softwareheritage/include/softwareheritagePlugin.class.php
@@ -148,6 +148,16 @@ function &softwareheritage_repositoryInfo($session_ser, $repository_id) {
 function &softwareheritage_repositoryActivity($session_ser, $t0, $t1) {
 	continue_session($session_ser);
 
+	if ($t1 < $t0) {
+		$t2 = $t1;
+		$t1 = $t0;
+		$t0 = $t2;
+	}
+	$maxspan = 86400*31;
+	if ($t1 - $t0 > $maxspan) {
+		$t0 = $t1 - $maxspan;
+	}
+
 	$params = array('t0' => $t0,
 					't1' => $t1);
 	$results = array();

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=b73af727012d54020405288fe0f5931ffa34742a

commit b73af727012d54020405288fe0f5931ffa34742a
Author: Roland Mas <lolando at debian.org>
Date:   Tue Dec 20 13:00:24 2016 +0100

    Implement repositoryActivity for scmsvn (with test)

diff --git a/src/plugins/scmsvn/common/SVNPlugin.class.php b/src/plugins/scmsvn/common/SVNPlugin.class.php
index 82cef6e..dc92643 100644
--- a/src/plugins/scmsvn/common/SVNPlugin.class.php
+++ b/src/plugins/scmsvn/common/SVNPlugin.class.php
@@ -58,6 +58,8 @@ some control over it to the project's administrator.");
 		$this->_addHook('scm_gather_stats');
 		$this->_addHook('get_scm_repo_list');
 		$this->_addHook('get_scm_repo_info');
+		$this->_addHook('get_scm_repo_activity');
+		$this->_addHook('parse_scm_repo_activities');
 		$this->_addHook('activity');
 
 		$this->provides['svn'] = true;
@@ -801,6 +803,55 @@ some control over it to the project's administrator.");
 			}
 		}
 	}
+
+    function parse_scm_repo_activities(&$params) {
+		$repos = array();
+		$res = db_query_params("SELECT unix_group_name, groups.group_id FROM groups
+			JOIN group_plugin ON (groups.group_id=group_plugin.group_id)
+			WHERE groups.status=$1 AND group_plugin.plugin_id=$2
+			ORDER BY unix_group_name", array('A', $this->getID()));
+		while ($arr = db_fetch_array($res)) {
+			$el = array();
+			$el['rpath'] = $this->svn_root_fs.'/'.$arr['unix_group_name'];
+			$el['rid'] = $arr['unix_group_name'].'/svn/'.$arr['unix_group_name'];
+			$el['gid'] = $arr['group_id'];
+			$repos[] = $el;
+		}
+
+		$lastactivities = array();
+		$res = db_query_params("SELECT repository_id, max(tstamp) AS last FROM scm_activities WHERE plugin_id=$1 GROUP BY repository_id",
+							   array($this->getID()));
+		while ($arr = db_fetch_array($res)) {
+			$lastactivities[$arr['repository_id']] = $arr['last'];
+		}
+		
+		foreach ($repos as $rdata) {
+			$since = "";
+			if (array_key_exists($rdata['rid'], $lastactivities)) {
+				$since = '-r {$(date -d @'.$lastactivities[$rdata['rid']].' -Iseconds)}:HEAD';
+			}
+			$rpath = $rdata['rpath'];
+			$tstamps = array();
+			$f = popen("svn log -q 'file:///$rpath' $since 2> /dev/null", "r");
+			while (($l = fgets($f, 4096)) !== false) {
+				if (preg_match("/.*?\|.*\|(?P<tstamp>[-0-9 :+]+)/", $l, $matches)) {
+					$t = strtotime($matches['tstamp']);
+					if (array_key_exists($rdata['rid'], $lastactivities)
+						&& $t <= $lastactivities[$rdata['rid']]) {
+						continue;
+					}
+					$tstamps[$t] = 1;
+				}
+			}
+			foreach ($tstamps as $t => $v) {
+				$res = db_query_params("INSERT INTO scm_activities (group_id, plugin_id, repository_id, tstamp) VALUES ($1,$2,$3,$4)",
+									   array($rdata['gid'],
+											 $this->getID(),
+											 $rdata['rid'],
+											 $t));
+			}
+		}
+	}
 }
 
 // End of class, helper functions now
diff --git a/tests/func/60_PluginsSoftwareHeritage/softwareheritageTest.php b/tests/func/60_PluginsSoftwareHeritage/softwareheritageTest.php
index b1cbe46..67f0adf 100644
--- a/tests/func/60_PluginsSoftwareHeritage/softwareheritageTest.php
+++ b/tests/func/60_PluginsSoftwareHeritage/softwareheritageTest.php
@@ -61,7 +61,10 @@ class SoftwareHeritage extends FForge_SeleniumTestCase
 		// Run the cronjob to create repositories
 		$this->waitSystasks();
 
-		// Get the address of the repo
+		sleep(1);
+		$t0 = time();
+
+		// Get the address of the Git repo
 		$this->open(ROOT);
 		$this->clickAndWait("link=ProjectA");
 		$this->clickAndWait("link=SCM");
@@ -112,10 +115,34 @@ class SoftwareHeritage extends FForge_SeleniumTestCase
 		$this->assertEquals(0, $ret);
 		$this->runCommandTimeout("$t/".FORGE_ADMIN_USERNAME, "git push --quiet --all", "GIT_SSL_NO_VERIFY=true");
 
+
+		// Get the address of the SVN repo
+		$this->open(ROOT);
+		$this->clickAndWait("link=ProjectB");
+		$this->clickAndWait("link=SCM");
+		$p = $this->getText("//tt[contains(.,'svn checkout --username ".FORGE_ADMIN_USERNAME." http')]");
+		$p = preg_replace(",^svn checkout --username ".FORGE_ADMIN_USERNAME." ,", "", $p);
+
+		// Create a local clone, add stuff, push it to the repo
+		$t = exec("mktemp -d /tmp/svnTest.XXXXXX");
+		$auth = "--username ".FORGE_ADMIN_USERNAME." --password ".FORGE_ADMIN_PASSWORD;
+		$globalopts = "--trust-server-cert --non-interactive";
+		$this->runCommandTimeout($t, "svn checkout $globalopts $auth $p projectb");
+		sleep(2);
+		$this->runCommand("echo 'this is a simple text' > $t/projectb/mytext.txt");
+		$this->runCommandTimeout("$t/projectb", "svn add mytext.txt");
+		$this->runCommandTimeout("$t/projectb", "svn commit $globalopts $auth -m'Adding file'");
+		sleep(2);
+		$this->runCommand("echo 'another simple text' >> $t/projectb/mytext.txt");
+		$this->runCommandTimeout("$t/projectb", "svn commit $globalopts $auth -m'Modifying file'");
+		sleep(2);
+
+
+		// Collect activities
 		$this->cron("scm/parse_scm_repo_activities.php");
 
-		// Check SOAP
 
+		// Check SOAP
 		$soapclient = new SoapClient(WSDL_URL,
 		array('cache_wsdl' => WSDL_CACHE_NONE,
 		'trace' => true));
@@ -164,10 +191,11 @@ class SoftwareHeritage extends FForge_SeleniumTestCase
 		$response = $soapclient->softwareheritage_repositoryInfo($session,'projectb/svn/projectb');
 		$this->assertNotEquals(NULL,$response);
 		$this->assertEquals(4,count($response->repository_urls));
-		
-		$response = $soapclient->softwareheritage_repositoryActivity($session,time()-120,time());
+
+		// Get activities for repositories		
+		$response = $soapclient->softwareheritage_repositoryActivity($session,$t0,time());
 		$this->assertNotEquals(NULL,$response);
-		$this->assertEquals(3,count($response));
+		$this->assertEquals(5,count($response));
 		sleep(15);
 		$response = $soapclient->softwareheritage_repositoryActivity($session,time()-10,time());
 		$this->assertNotEquals(NULL,$response);

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=65678dc480430d468ccd0e684954b0b6acd85c6b

commit 65678dc480430d468ccd0e684954b0b6acd85c6b
Author: Roland Mas <lolando at debian.org>
Date:   Tue Dec 20 12:27:13 2016 +0100

    Implement repositoryActivity for scmgit (with test)

diff --git a/src/common/include/SCMPlugin.class.php b/src/common/include/SCMPlugin.class.php
index 8cecf82..296e798 100644
--- a/src/common/include/SCMPlugin.class.php
+++ b/src/common/include/SCMPlugin.class.php
@@ -333,6 +333,18 @@ abstract class SCMPlugin extends Plugin {
 		return true;
 	}
 
+    function get_scm_repo_activity(&$params) {
+		$res = db_query_params("SELECT tstamp, repository_id, group_id FROM scm_activities WHERE plugin_id=$1 AND tstamp BETWEEN $2 AND $3 ORDER BY group_id, repository_id, tstamp",
+							   array($this->getID(),
+									 $params['t0'],
+									 $params['t1']));
+		while ($arr = db_fetch_array($res)) {
+			$params['results'][] = array('timestamp' => $arr['tstamp'],
+										 'repository_id' => $arr['repository_id'],
+										 'group_id' => $arr['group_id']);
+		}
+	}
+
 	function checkParams ($params) {
 		$group_id = $params['group_id'] ;
 		$project = group_get_object($group_id);
diff --git a/src/cronjobs/scm/parse_scm_repo_activities.php b/src/cronjobs/scm/parse_scm_repo_activities.php
new file mode 100755
index 0000000..b97f29f
--- /dev/null
+++ b/src/cronjobs/scm/parse_scm_repo_activities.php
@@ -0,0 +1,45 @@
+#!/usr/bin/php
+<?php
+/**
+ * FusionForge source control management
+ *
+ * Copyright 2016, Roland Mas
+ *
+ * This file is part of FusionForge. FusionForge 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 2 of the Licence, or (at your option)
+ * any later version.
+ *
+ * FusionForge 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 FusionForge; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+require (dirname(__FILE__).'/../../common/include/env.inc.php');
+require_once $gfcommon.'include/pre.php';
+require_once $gfcommon.'include/cron_utils.php';
+
+// Plugins subsystem
+require_once $gfcommon.'include/Plugin.class.php' ;
+require_once $gfcommon.'include/PluginManager.class.php' ;
+
+// SCM-specific plugins subsystem
+require_once $gfcommon.'include/SCMPlugin.class.php' ;
+
+session_set_admin () ;
+
+setup_plugin_manager () ;
+
+$hook_params = array();
+plugin_hook ('parse_scm_repo_activities', $hook_params) ;
+
+// Local Variables:
+// mode: php
+// c-file-style: "bsd"
+// End:
diff --git a/src/db/20161220-repository-activities.sql b/src/db/20161220-repository-activities.sql
new file mode 100644
index 0000000..c8a2394
--- /dev/null
+++ b/src/db/20161220-repository-activities.sql
@@ -0,0 +1,7 @@
+CREATE TABLE scm_activities (
+  group_id INTEGER NOT NULL REFERENCES GROUPS ON DELETE CASCADE ON UPDATE CASCADE,
+  plugin_id INTEGER NOT NULL REFERENCES plugins ON DELETE CASCADE ON UPDATE CASCADE,
+  repository_id TEXT NOT NULL,
+  tstamp INTEGER NOT NULL
+);
+CREATE INDEX scm_activities_rid_idx ON scm_activities USING btree(repository_id);
diff --git a/src/etc/cron.d/fusionforge-scm b/src/etc/cron.d/fusionforge-scm
index 332aa46..80f4256 100644
--- a/src/etc/cron.d/fusionforge-scm
+++ b/src/etc/cron.d/fusionforge-scm
@@ -8,3 +8,6 @@ PATH=@bindir@:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
 
 # Generate snapshots and tarballs from SCM repositories
 0 3 * * * root forge_run_job scm/generate_scm_snapshots.php
+
+# Gather activities from SCM repositories
+0 3 * * * root forge_run_job scm/parse_scm_repo_activities.php
diff --git a/src/plugins/scmgit/common/GitPlugin.class.php b/src/plugins/scmgit/common/GitPlugin.class.php
index d6da621..cbc835c 100644
--- a/src/plugins/scmgit/common/GitPlugin.class.php
+++ b/src/plugins/scmgit/common/GitPlugin.class.php
@@ -55,6 +55,8 @@ control over it to the project's administrator.");
 		$this->_addHook('scm_delete_repo');
 		$this->_addHook('get_scm_repo_list');
 		$this->_addHook('get_scm_repo_info');
+		$this->_addHook('get_scm_repo_activity');
+		$this->_addHook('parse_scm_repo_activities');
 		$this->_addHook('widget_instance', 'myPageBox', false);
 		$this->_addHook('widgets', 'widgets', false);
 		$this->_addHook('activity');
@@ -408,6 +410,8 @@ control over it to the project's administrator.");
 			system("cd $root; LC_ALL=C git clone --bare --quiet --no-hardlinks $main_repo $repodir 2>&1 >/dev/null | grep -v 'warning: You appear to have cloned an empty repository.' >&2");
 			system("GIT_DIR=\"$repodir\" git update-server-info");
 			system("GIT_DIR=\"$repodir\" git config http.receivepack true");
+			system("GIT_DIR=\"$repodir\" git config core.logAllRefUpdates true");
+
 			if (is_file("$repodir/hooks/post-update.sample")) {
 				rename("$repodir/hooks/post-update.sample",
 					"$repodir/hooks/post-update");
@@ -462,6 +466,7 @@ control over it to the project's administrator.");
 			$result = '';
 			exec("GIT_DIR=\"$tmp_repo\" git update-server-info", $result);
 			exec("GIT_DIR=\"$tmp_repo\" git config http.receivepack true", $result);
+			exec("GIT_DIR=\"$tmp_repo\" git config core.logAllRefUpdates true");
 			$output .= join("<br />", $result);
 			if (is_file("$tmp_repo/hooks/post-update.sample")) {
 				rename("$tmp_repo/hooks/post-update.sample",
@@ -518,6 +523,7 @@ control over it to the project's administrator.");
 				}
 				system("GIT_DIR=\"$repodir\" git update-server-info");
 				system("GIT_DIR=\"$repodir\" git config http.receivepack true");
+				system("GIT_DIR=\"$repodir\" git config core.logAllRefUpdates true");
 				if (is_file("$repodir/hooks/post-update.sample")) {
 					rename("$repodir/hooks/post-update.sample",
 						"$repodir/hooks/post-update");
@@ -1393,6 +1399,83 @@ control over it to the project's administrator.");
 			}
 		}
 	}
+
+    function parse_scm_repo_activities(&$params) {
+		$repos = array();
+		$res = db_query_params("SELECT unix_group_name, groups.group_id FROM groups
+			JOIN group_plugin ON (groups.group_id=group_plugin.group_id)
+			WHERE groups.status=$1 AND group_plugin.plugin_id=$2
+			ORDER BY unix_group_name", array('A', $this->getID()));
+		while ($arr = db_fetch_array($res)) {
+			$el = array();
+			$el['rpath'] = forge_get_config('repos_path', 'scmgit') .'/'. $arr['unix_group_name'] .'/'. $arr['unix_group_name'] .'.git';
+			$el['rid'] = $arr['unix_group_name'].'/git/'.$arr['unix_group_name'];
+			$el['gid'] = $arr['group_id'];
+			$repos[] = $el;
+		}
+
+		$res = db_query_params("SELECT unix_group_name, groups.group_id, repo_name
+			FROM groups
+			JOIN group_plugin ON (groups.group_id=group_plugin.group_id)
+			JOIN scm_secondary_repos ON (groups.group_id=scm_secondary_repos.group_id)
+			WHERE groups.status=$1 AND group_plugin.plugin_id=$2
+			ORDER BY unix_group_name, repo_name", array('A', $this->getID()));
+		while ($arr = db_fetch_array($res)) {
+			$el = array();
+			$el['rpath'] = forge_get_config('repos_path', 'scmgit') .'/'. $arr['unix_group_name'] .'/'. $arr['repo_name'] .'.git';
+			$el['rid'] = $arr['unix_group_name'].'/git/'.$arr['repo_name'];
+			$el['gid'] = $arr['group_id'];
+			$repos[] = $el;
+		}
+
+		$res = db_query_params("SELECT unix_group_name, groups.group_id, user_name
+			FROM groups
+			JOIN group_plugin ON (groups.group_id=group_plugin.group_id)
+			JOIN scm_personal_repos ON (groups.group_id=scm_personal_repos.group_id)
+			JOIN users ON (scm_personal_repos.user_id=users.user_id)
+			WHERE groups.status=$1 AND group_plugin.plugin_id=$2 AND users.status=$3
+			ORDER BY unix_group_name, user_name", array('A', $this->getID(), 'A'));
+		while ($arr = db_fetch_array($res)) {
+			$el = array();
+			$el['rpath'] = forge_get_config('repos_path', 'scmgit') .'/'. $arr['unix_group_name'] .'/users/'. $arr['user_name'] .'.git';
+			$el['rid'] = $arr['unix_group_name'].'/git/users/'.$arr['user_name'];
+			$el['gid'] = $arr['group_id'];
+			$repos[] = $el;
+		}
+
+		$lastactivities = array();
+		$res = db_query_params("SELECT repository_id, max(tstamp) AS last FROM scm_activities WHERE plugin_id=$1 GROUP BY repository_id",
+							   array($this->getID()));
+		while ($arr = db_fetch_array($res)) {
+			$lastactivities[$arr['repository_id']] = $arr['last'];
+		}
+		
+		foreach ($repos as $rdata) {
+			$since = "";
+			if (array_key_exists($rdata['rid'], $lastactivities)) {
+				$since = "--since=@".$lastactivities[$rdata['rid']];
+			}
+			$rpath = $rdata['rpath'];
+			$tstamps = array();
+			$f = popen("GIT_DIR=\"$rpath\" git reflog --date=raw --all $since 2> /dev/null", "r");
+			while (($l = fgets($f, 4096)) !== false) {
+				if (preg_match("/@\{(?P<tstamp>[0-9]+) [-+0-9]+\}: push/", $l, $matches)) {
+					if (array_key_exists($rdata['rid'], $lastactivities)
+						&& $matches['tstamp'] <= $lastactivities[$rdata['rid']]) {
+						continue;
+					}
+					$tstamps[$matches['tstamp']] = 1;
+				}
+			}
+			foreach ($tstamps as $t => $v) {
+				$res = db_query_params("INSERT INTO scm_activities (group_id, plugin_id, repository_id, tstamp) VALUES ($1,$2,$3,$4)",
+									   array($rdata['gid'],
+											 $this->getID(),
+											 $rdata['rid'],
+											 $t));
+			}
+		}
+	}
 }
 
 // Local Variables:
diff --git a/src/plugins/softwareheritage/include/softwareheritagePlugin.class.php b/src/plugins/softwareheritage/include/softwareheritagePlugin.class.php
index 173a0fd..e2646ea 100644
--- a/src/plugins/softwareheritage/include/softwareheritagePlugin.class.php
+++ b/src/plugins/softwareheritage/include/softwareheritagePlugin.class.php
@@ -71,6 +71,40 @@ class softwareheritagePlugin extends Plugin {
 			array('return'=>'tns:SoftwareheritageRepositoryInfo'),
 			$uri,
                        $uri.'#softwareheritage_repositoryInfo','rpc','encoded');
+
+		$server->wsdl->addComplexType(
+			'SoftwareheritageActivity',
+			'complexType',
+			'struct',
+			'sequence',
+			'',
+			array(
+				'group_id' => array('name'=>'group_id', 'type' => 'xsd:int'),
+				'repository_id' => array('name'=>'repository_id', 'type' => 'xsd:string'),
+				'timestamp' => array('name'=>'timestamp', 'type' => 'xsd:int'),
+				)
+			);
+
+		$server->wsdl->addComplexType(
+			'ArrayOfSoftwareheritageActivity',
+			'complexType',
+			'array',
+			'',
+			'SOAP-ENC:Array',
+			array(),
+			array(array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'tns:SoftwareheritageActivity[]')),
+			'tns:SoftwareheritageActivity');
+               
+		$server->register(
+			'softwareheritage_repositoryActivity',
+			array('session_ser'=>'xsd:string',
+				  't0'=>'xsd:int',
+				  't1'=>'xsd:int'
+				),
+			array('return'=>'tns:ArrayOfSoftwareheritageActivity'),
+			$uri,
+                       $uri.'#softwareheritage_repositoryActivity','rpc','encoded');
+
 	}
 
 
@@ -79,6 +113,7 @@ class softwareheritagePlugin extends Plugin {
 function &softwareheritage_repositoryList($session_ser) {
 	continue_session($session_ser);
 
+	$params = array();
 	$results = array();
 	$params['results'] = &$results;
 	plugin_hook('get_scm_repo_list',$params);
@@ -96,6 +131,7 @@ function &softwareheritage_repositoryList($session_ser) {
 function &softwareheritage_repositoryInfo($session_ser, $repository_id) {
 	continue_session($session_ser);
 
+	$params = array();
 	$results = NULL;
 	$params['repository_id'] = $repository_id;
 	$params['results'] = &$results;
@@ -109,6 +145,25 @@ function &softwareheritage_repositoryInfo($session_ser, $repository_id) {
 	return $params['results'];
 }
 
+function &softwareheritage_repositoryActivity($session_ser, $t0, $t1) {
+	continue_session($session_ser);
+
+	$params = array('t0' => $t0,
+					't1' => $t1);
+	$results = array();
+	$params['results'] = &$results;
+	plugin_hook('get_scm_repo_activity',$params);
+
+	$res2 = array();
+	foreach ($results as $res) {
+		if (forge_check_perm('scm',$res['group_id'],'read')) {
+			$res2[] = $res;
+		}
+	}
+
+	return $res2;
+}
+
 // Local Variables:
 // mode: php
 // c-file-style: "bsd"
diff --git a/tests/func/60_PluginsSoftwareHeritage/softwareheritageTest.php b/tests/func/60_PluginsSoftwareHeritage/softwareheritageTest.php
index 9d72dfd..b1cbe46 100644
--- a/tests/func/60_PluginsSoftwareHeritage/softwareheritageTest.php
+++ b/tests/func/60_PluginsSoftwareHeritage/softwareheritageTest.php
@@ -61,6 +61,58 @@ class SoftwareHeritage extends FForge_SeleniumTestCase
 		// Run the cronjob to create repositories
 		$this->waitSystasks();
 
+		// Get the address of the repo
+		$this->open(ROOT);
+		$this->clickAndWait("link=ProjectA");
+		$this->clickAndWait("link=SCM");
+		$p = $this->getText("//tt[contains(.,'git clone http') and contains(.,'".FORGE_ADMIN_USERNAME."@') and contains(.,'projecta.git')]");
+		$p = preg_replace(",^git clone ,", "", $p);
+		$p = preg_replace(",@,", ":".FORGE_ADMIN_PASSWORD."@", $p);
+
+		// Create a local clone, add stuff, push it to the repo
+		$t = exec("mktemp -d /tmp/gitTest.XXXXXX");
+		$this->runCommandTimeout($t, "git clone --quiet $p", "GIT_SSL_NO_VERIFY=true");
+
+		system("echo 'this is a simple text' > $t/projecta/mytext.txt");
+		system("cd $t/projecta && git add mytext.txt && git commit --quiet -a -m'Adding file'", $ret);
+		system("echo 'another simple text' >> $t/projecta/mytext.txt");
+		system("cd $t/projecta && git commit --quiet -a -m'Modifying file'", $ret);
+		$this->assertEquals(0, $ret);
+		$this->runCommandTimeout("$t/projecta", "git push --quiet --all", "GIT_SSL_NO_VERIFY=true");
+
+		// Push a second batch of changes after a while
+		sleep(2);
+		system("echo 'yet another simple text' >> $t/projecta/mytext.txt");
+		system("cd $t/projecta && git commit --quiet -a -m'Modifying file again'", $ret);
+		$this->assertEquals(0, $ret);
+		$this->runCommandTimeout("$t/projecta", "git push --quiet --all", "GIT_SSL_NO_VERIFY=true");
+		system("cd $t/projecta && git commit --quiet -a -m'Modifying file again'", $ret);
+
+		// Push a third batch of changes, on a branch
+		system("cd $t/projecta && git checkout -b testbranch", $ret);
+		system("echo 'text on a branch' >> $t/projecta/mytext.txt");
+		system("cd $t/projecta && git commit --quiet -a -m'Modifying file on the branch'", $ret);
+		$this->assertEquals(0, $ret);
+		$this->runCommandTimeout("$t/projecta", "git push --quiet --all", "GIT_SSL_NO_VERIFY=true");
+
+		// Get the address of the personal repo
+		$this->open(ROOT);
+		$this->clickAndWait("link=ProjectA");
+		$this->clickAndWait("link=SCM");
+		$p = $this->getText("//tt[contains(.,'git clone http') and contains(.,'".FORGE_ADMIN_USERNAME."@') and contains(.,'".FORGE_ADMIN_USERNAME.".git')]");
+		$p = preg_replace(",^git clone ,", "", $p);
+		$p = preg_replace(",@,", ":".FORGE_ADMIN_PASSWORD."@", $p);
+
+		// Create a local clone, add stuff, push it to the repo
+		$t = exec("mktemp -d /tmp/gitTest.XXXXXX");
+		$this->runCommandTimeout($t, "git clone --quiet $p", "GIT_SSL_NO_VERIFY=true");
+
+		system("echo 'text in personal repo' > $t/".FORGE_ADMIN_USERNAME."/mytext.txt");
+		system("cd $t/".FORGE_ADMIN_USERNAME." && git add mytext.txt && git commit --quiet -a -m'Adding file'", $ret);
+		$this->assertEquals(0, $ret);
+		$this->runCommandTimeout("$t/".FORGE_ADMIN_USERNAME, "git push --quiet --all", "GIT_SSL_NO_VERIFY=true");
+
+		$this->cron("scm/parse_scm_repo_activities.php");
 
 		// Check SOAP
 
@@ -113,5 +165,12 @@ class SoftwareHeritage extends FForge_SeleniumTestCase
 		$this->assertNotEquals(NULL,$response);
 		$this->assertEquals(4,count($response->repository_urls));
 		
+		$response = $soapclient->softwareheritage_repositoryActivity($session,time()-120,time());
+		$this->assertNotEquals(NULL,$response);
+		$this->assertEquals(3,count($response));
+		sleep(15);
+		$response = $soapclient->softwareheritage_repositoryActivity($session,time()-10,time());
+		$this->assertNotEquals(NULL,$response);
+		$this->assertEquals(0,count($response));
 	}
 }

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=9597ff374284f662611b85dfe7423dfabcd3df43

commit 9597ff374284f662611b85dfe7423dfabcd3df43
Author: Roland Mas <lolando at debian.org>
Date:   Tue Dec 13 12:27:44 2016 +0100

    Implement repositoryInfo for scmsvn (with test)

diff --git a/src/plugins/scmsvn/common/SVNPlugin.class.php b/src/plugins/scmsvn/common/SVNPlugin.class.php
index 952ee0b..82cef6e 100644
--- a/src/plugins/scmsvn/common/SVNPlugin.class.php
+++ b/src/plugins/scmsvn/common/SVNPlugin.class.php
@@ -57,6 +57,7 @@ some control over it to the project's administrator.");
 		$this->_addHook('scm_generate_snapshots');
 		$this->_addHook('scm_gather_stats');
 		$this->_addHook('get_scm_repo_list');
+		$this->_addHook('get_scm_repo_info');
 		$this->_addHook('activity');
 
 		$this->provides['svn'] = true;
@@ -730,6 +731,11 @@ some control over it to the project's administrator.");
 	}
 
     function get_scm_repo_list(&$params) {
+		if (array_key_exists('group_name',$params)) {
+			$unix_group_name = $params['group_name'];
+		} else {
+			$unix_group_name = '';
+		}
 		$protocol = forge_get_config('use_ssl', 'scmsvn')? 'https' : 'http';
 		if (session_loggedin()) {
 			$u = user_get_object(user_getid());
@@ -737,10 +743,17 @@ some control over it to the project's administrator.");
 		}
 		
 		$results = array();
-		$res = db_query_params("SELECT unix_group_name, groups.group_id FROM groups
+		if ($unix_group_name) {
+			$res = db_query_params("SELECT unix_group_name, groups.group_id FROM groups
+			JOIN group_plugin ON (groups.group_id=group_plugin.group_id)
+			WHERE groups.status=$1 AND group_plugin.plugin_id=$2 AND groups.unix_group_name=$3
+			ORDER BY unix_group_name", array('A', $this->getID(),$unix_group_name));
+		} else {
+			$res = db_query_params("SELECT unix_group_name, groups.group_id FROM groups
 			JOIN group_plugin ON (groups.group_id=group_plugin.group_id)
 			WHERE groups.status=$1 AND group_plugin.plugin_id=$2
 			ORDER BY unix_group_name", array('A', $this->getID()));
+		}			
 		while ($arr = db_fetch_array($res)) {
 			if (!forge_check_perm('scm', $arr['group_id'], 'read')) {
 				continue;
@@ -771,6 +784,23 @@ some control over it to the project's administrator.");
 			$params['results'][] = $res;
 		}
 	}
+
+    function get_scm_repo_info(&$params) {
+		$rid = $params['repository_id'];
+		$e = explode('/',$rid);
+		if ($e[1] != 'svn') {
+			return;
+		}
+		$g = $e[0];
+		$p = array('group_name' => $g);
+		$this->get_scm_repo_list($p);
+		foreach ($p['results'] as $r) {
+			if ($r['repository_id'] == $rid) {
+				$params['results'] = $r;
+				return;
+			}
+		}
+	}
 }
 
 // End of class, helper functions now
diff --git a/tests/func/60_PluginsSoftwareHeritage/softwareheritageTest.php b/tests/func/60_PluginsSoftwareHeritage/softwareheritageTest.php
index 8813fe5..9d72dfd 100644
--- a/tests/func/60_PluginsSoftwareHeritage/softwareheritageTest.php
+++ b/tests/func/60_PluginsSoftwareHeritage/softwareheritageTest.php
@@ -108,5 +108,10 @@ class SoftwareHeritage extends FForge_SeleniumTestCase
 		$response = $soapclient->softwareheritage_repositoryInfo($session,'projecta/git/projecta');
 		$this->assertNotEquals(NULL,$response);
 		$this->assertEquals(3,count($response->repository_urls));
+		
+		$response = $soapclient->softwareheritage_repositoryInfo($session,'projectb/svn/projectb');
+		$this->assertNotEquals(NULL,$response);
+		$this->assertEquals(4,count($response->repository_urls));
+		
 	}
 }

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=b98d0c57a5528da183a176a313758394b3b10b83

commit b98d0c57a5528da183a176a313758394b3b10b83
Author: Roland Mas <lolando at debian.org>
Date:   Tue Dec 13 12:17:21 2016 +0100

    Implement repositoryInfo for scmgit (with test)

diff --git a/src/plugins/scmgit/common/GitPlugin.class.php b/src/plugins/scmgit/common/GitPlugin.class.php
index 9e82c92..d6da621 100644
--- a/src/plugins/scmgit/common/GitPlugin.class.php
+++ b/src/plugins/scmgit/common/GitPlugin.class.php
@@ -54,6 +54,7 @@ control over it to the project's administrator.");
 		$this->_addHook('scm_add_repo');
 		$this->_addHook('scm_delete_repo');
 		$this->_addHook('get_scm_repo_list');
+		$this->_addHook('get_scm_repo_info');
 		$this->_addHook('widget_instance', 'myPageBox', false);
 		$this->_addHook('widgets', 'widgets', false);
 		$this->_addHook('activity');
@@ -1248,8 +1249,12 @@ control over it to the project's administrator.");
 		return $commits;
 	}
 
-
     function get_scm_repo_list(&$params) {
+		if (array_key_exists('group_name',$params)) {
+			$unix_group_name = $params['group_name'];
+		} else {
+			$unix_group_name = '';
+		}
 		$protocol = forge_get_config('use_ssl', 'scmgit')? 'https' : 'http';
 		if (session_loggedin()) {
 			$u = user_get_object(user_getid());
@@ -1257,10 +1262,17 @@ control over it to the project's administrator.");
 		}
 		
 		$results = array();
-		$res = db_query_params("SELECT unix_group_name, groups.group_id FROM groups
+		if ($unix_group_name) {
+			$res = db_query_params("SELECT unix_group_name, groups.group_id FROM groups
+			JOIN group_plugin ON (groups.group_id=group_plugin.group_id)
+			WHERE groups.status=$1 AND group_plugin.plugin_id=$2 AND groups.unix_group_name=$3
+			ORDER BY unix_group_name", array('A', $this->getID(), $unix_group_name));
+		} else {
+			$res = db_query_params("SELECT unix_group_name, groups.group_id FROM groups
 			JOIN group_plugin ON (groups.group_id=group_plugin.group_id)
 			WHERE groups.status=$1 AND group_plugin.plugin_id=$2
 			ORDER BY unix_group_name", array('A', $this->getID()));
+		}
 		while ($arr = db_fetch_array($res)) {
 			if (!forge_check_perm('scm', $arr['group_id'], 'read')) {
 				continue;
@@ -1283,12 +1295,21 @@ control over it to the project's administrator.");
 							   'repository_urls' => $urls,
 				);
 		}
-		$res = db_query_params("SELECT unix_group_name, groups.group_id, repo_name
+		if ($unix_group_name) {
+			$res = db_query_params("SELECT unix_group_name, groups.group_id, repo_name
+			FROM groups
+			JOIN group_plugin ON (groups.group_id=group_plugin.group_id)
+			JOIN scm_secondary_repos ON (groups.group_id=scm_secondary_repos.group_id)
+			WHERE groups.status=$1 AND group_plugin.plugin_id=$2 AND groups.unix_group_name=$3
+			ORDER BY unix_group_name, repo_name", array('A', $this->getID(), $unix_group_name));
+		} else {
+			$res = db_query_params("SELECT unix_group_name, groups.group_id, repo_name
 			FROM groups
 			JOIN group_plugin ON (groups.group_id=group_plugin.group_id)
 			JOIN scm_secondary_repos ON (groups.group_id=scm_secondary_repos.group_id)
 			WHERE groups.status=$1 AND group_plugin.plugin_id=$2
 			ORDER BY unix_group_name, repo_name", array('A', $this->getID()));
+		}
 		while ($arr = db_fetch_array($res)) {
 			if (!forge_check_perm('scm', $arr['group_id'], 'read')) {
 				continue;
@@ -1311,13 +1332,23 @@ control over it to the project's administrator.");
 							   'repository_urls' => $urls,
 				);
 		}
-		$res = db_query_params("SELECT unix_group_name, groups.group_id, user_name
+		if ($unix_group_name) {
+			$res = db_query_params("SELECT unix_group_name, groups.group_id, user_name
+			FROM groups
+			JOIN group_plugin ON (groups.group_id=group_plugin.group_id)
+			JOIN scm_personal_repos ON (groups.group_id=scm_personal_repos.group_id)
+			JOIN users ON (scm_personal_repos.user_id=users.user_id)
+			WHERE groups.status=$1 AND group_plugin.plugin_id=$2 AND users.status=$3 AND groups.unix_group_name=$4
+			ORDER BY unix_group_name, user_name", array('A', $this->getID(), 'A', $unix_group_name));
+		} else {
+			$res = db_query_params("SELECT unix_group_name, groups.group_id, user_name
 			FROM groups
 			JOIN group_plugin ON (groups.group_id=group_plugin.group_id)
 			JOIN scm_personal_repos ON (groups.group_id=scm_personal_repos.group_id)
 			JOIN users ON (scm_personal_repos.user_id=users.user_id)
 			WHERE groups.status=$1 AND group_plugin.plugin_id=$2 AND users.status=$3
 			ORDER BY unix_group_name, user_name", array('A', $this->getID(), 'A'));
+		}			
 		while ($arr = db_fetch_array($res)) {
 			if (!forge_check_perm('scm', $arr['group_id'], 'read')) {
 				continue;
@@ -1345,6 +1376,23 @@ control over it to the project's administrator.");
 			$params['results'][] = $res;
 		}
 	}
+
+    function get_scm_repo_info(&$params) {
+		$rid = $params['repository_id'];
+		$e = explode('/',$rid);
+		if ($e[1] != 'git') {
+			return;
+		}
+		$g = $e[0];
+		$p = array('group_name' => $g);
+		$this->get_scm_repo_list($p);
+		foreach ($p['results'] as $r) {
+			if ($r['repository_id'] == $rid) {
+				$params['results'] = $r;
+				return;
+			}
+		}
+	}
 }
 
 // Local Variables:
diff --git a/src/plugins/softwareheritage/include/softwareheritagePlugin.class.php b/src/plugins/softwareheritage/include/softwareheritagePlugin.class.php
index 9f854e7..173a0fd 100644
--- a/src/plugins/softwareheritage/include/softwareheritagePlugin.class.php
+++ b/src/plugins/softwareheritage/include/softwareheritagePlugin.class.php
@@ -63,6 +63,14 @@ class softwareheritagePlugin extends Plugin {
 			array('return'=>'tns:ArrayOfSoftwareheritageRepositoryInfo'),
 			$uri,
                        $uri.'#softwareheritage_repositoryList','rpc','encoded');
+
+		$server->register(
+			'softwareheritage_repositoryInfo',
+			array('session_ser'=>'xsd:string',
+				'repository_id'=>'xsd:string'),
+			array('return'=>'tns:SoftwareheritageRepositoryInfo'),
+			$uri,
+                       $uri.'#softwareheritage_repositoryInfo','rpc','encoded');
 	}
 
 
@@ -85,6 +93,22 @@ function &softwareheritage_repositoryList($session_ser) {
 	return $res2;
 }
 
+function &softwareheritage_repositoryInfo($session_ser, $repository_id) {
+	continue_session($session_ser);
+
+	$results = NULL;
+	$params['repository_id'] = $repository_id;
+	$params['results'] = &$results;
+	plugin_hook('get_scm_repo_info',$params);
+
+	if ($params['results'] == NULL) {
+		$sf = new soap_fault('','softwareheritage_repositoryInfo',_('Error when fetching repository info'),_('Error when fetching repository info'));
+		return $sf;
+	}
+
+	return $params['results'];
+}
+
 // Local Variables:
 // mode: php
 // c-file-style: "bsd"
diff --git a/tests/func/60_PluginsSoftwareHeritage/softwareheritageTest.php b/tests/func/60_PluginsSoftwareHeritage/softwareheritageTest.php
index 14e1797..8813fe5 100644
--- a/tests/func/60_PluginsSoftwareHeritage/softwareheritageTest.php
+++ b/tests/func/60_PluginsSoftwareHeritage/softwareheritageTest.php
@@ -103,5 +103,10 @@ class SoftwareHeritage extends FForge_SeleniumTestCase
 
 		$this->assertTrue(array_key_exists('projectb/svn/projectb',$repos));
 		$this->assertEquals(2,count($repos['projectb/svn/projectb']->repository_urls));
+
+		// Get repository info as admin
+		$response = $soapclient->softwareheritage_repositoryInfo($session,'projecta/git/projecta');
+		$this->assertNotEquals(NULL,$response);
+		$this->assertEquals(3,count($response->repository_urls));
 	}
 }

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=53fcc1d00def6270b2855ccf2e8b43db0d46dfd3

commit 53fcc1d00def6270b2855ccf2e8b43db0d46dfd3
Author: Roland Mas <lolando at debian.org>
Date:   Tue Dec 13 11:33:20 2016 +0100

    Removed debugging aid

diff --git a/src/plugins/softwareheritage/include/softwareheritagePlugin.class.php b/src/plugins/softwareheritage/include/softwareheritagePlugin.class.php
index 258e145..9f854e7 100644
--- a/src/plugins/softwareheritage/include/softwareheritagePlugin.class.php
+++ b/src/plugins/softwareheritage/include/softwareheritagePlugin.class.php
@@ -75,8 +75,6 @@ function &softwareheritage_repositoryList($session_ser) {
 	$params['results'] = &$results;
 	plugin_hook('get_scm_repo_list',$params);
 
-	error_log(print_r($params,true));
-
 	$res2 = array();
 	foreach ($results as $res) {
 		if (forge_check_perm('scm',$res['group_id'],'read')) {

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=3a4da32a472138509b04c77ba9eea5788e5d3ee7

commit 3a4da32a472138509b04c77ba9eea5788e5d3ee7
Author: Roland Mas <lolando at debian.org>
Date:   Tue Dec 13 11:24:13 2016 +0100

    Implement repositoryList for scmsvn (with test)
    
    The softwareheritage_repositoryList SOAP method is now implemented for
    Subversion.  It returns the primary repository, the secondary repositories,
    and the users' repositories.  The returned URLs depend on the
    permissions of the currently logged-in user, and include the anonymous
    access URL as well as the authenticated access URLs when relevant.

diff --git a/src/plugins/scmsvn/common/SVNPlugin.class.php b/src/plugins/scmsvn/common/SVNPlugin.class.php
index 6967bb4..952ee0b 100644
--- a/src/plugins/scmsvn/common/SVNPlugin.class.php
+++ b/src/plugins/scmsvn/common/SVNPlugin.class.php
@@ -56,6 +56,7 @@ some control over it to the project's administrator.");
 		$this->_addHook('scm_regen_apache_auth');
 		$this->_addHook('scm_generate_snapshots');
 		$this->_addHook('scm_gather_stats');
+		$this->_addHook('get_scm_repo_list');
 		$this->_addHook('activity');
 
 		$this->provides['svn'] = true;
@@ -727,6 +728,49 @@ some control over it to the project's administrator.");
 		}
 		return $revisionsArr;
 	}
+
+    function get_scm_repo_list(&$params) {
+		$protocol = forge_get_config('use_ssl', 'scmsvn')? 'https' : 'http';
+		if (session_loggedin()) {
+			$u = user_get_object(user_getid());
+			$d = $u->getUnixName();
+		}
+		
+		$results = array();
+		$res = db_query_params("SELECT unix_group_name, groups.group_id FROM groups
+			JOIN group_plugin ON (groups.group_id=group_plugin.group_id)
+			WHERE groups.status=$1 AND group_plugin.plugin_id=$2
+			ORDER BY unix_group_name", array('A', $this->getID()));
+		while ($arr = db_fetch_array($res)) {
+			if (!forge_check_perm('scm', $arr['group_id'], 'read')) {
+				continue;
+			}
+			$urls = array();
+			if (forge_get_config('use_dav', 'scmsvn')) {
+				$urls[] = $protocol.'://'.forge_get_config('scm_host').'/anonscm/svn/'.$arr['unix_group_name'];
+			}
+			if (forge_get_config('use_ssh', 'scmsvn')) {
+				$urls[] = 'svn://'.forge_get_config('scm_host').$this->svn_root_fs.'/'.$arr['unix_group_name'];
+			}
+			if (session_loggedin()) {
+				if (forge_get_config('use_dav', 'scmsvn')) {
+					$urls[] = $protocol.'://'.forge_get_config('scm_host').'/authscm/'.$d.'/svn/'.$arr['unix_group_name'];
+				}
+				if (forge_get_config('use_ssh', 'scmsvn')) {
+					$urls[] = 'svn+ssh://'.$d.'@' . forge_get_config('scm_host') . $this->svn_root_fs .'/'. $arr['unix_group_name'];
+				}
+			}
+			$results[] = array('group_id' => $arr['group_id'],
+							   'repository_type' => 'svn',
+							   'repository_id' => $arr['unix_group_name'].'/svn/'.$arr['unix_group_name'],
+							   'repository_urls' => $urls,
+				);
+		}
+
+		foreach ($results as $res) {
+			$params['results'][] = $res;
+		}
+	}
 }
 
 // End of class, helper functions now
diff --git a/tests/func/60_PluginsSoftwareHeritage/softwareheritageTest.php b/tests/func/60_PluginsSoftwareHeritage/softwareheritageTest.php
index 36c0eca..14e1797 100644
--- a/tests/func/60_PluginsSoftwareHeritage/softwareheritageTest.php
+++ b/tests/func/60_PluginsSoftwareHeritage/softwareheritageTest.php
@@ -56,6 +56,8 @@ class SoftwareHeritage extends FForge_SeleniumTestCase
 		$this->clickAndWait("link=Request a personal repository");
 		$this->assertTextPresent("You have now requested a personal Git repository");
 
+		$this->createProject('ProjectB','scmsvn');
+
 		// Run the cronjob to create repositories
 		$this->waitSystasks();
 
@@ -85,6 +87,9 @@ class SoftwareHeritage extends FForge_SeleniumTestCase
 		$this->assertTrue(array_key_exists('projecta/git/other-repo',$repos));
 		$this->assertTrue(array_key_exists('projecta/git/users/admin',$repos));
 
+		$this->assertTrue(array_key_exists('projectb/svn/projectb',$repos));
+		$this->assertEquals(4,count($repos['projectb/svn/projectb']->repository_urls));
+
 		// Get repository list as anonymous
 		$response = $soapclient->softwareheritage_repositoryList('');
 		$repos = array();
@@ -95,5 +100,8 @@ class SoftwareHeritage extends FForge_SeleniumTestCase
 		$this->assertEquals(1,count($repos['projecta/git/projecta']->repository_urls));
 		$this->assertTrue(array_key_exists('projecta/git/other-repo',$repos));
 		$this->assertTrue(array_key_exists('projecta/git/users/admin',$repos));
+
+		$this->assertTrue(array_key_exists('projectb/svn/projectb',$repos));
+		$this->assertEquals(2,count($repos['projectb/svn/projectb']->repository_urls));
 	}
 }

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=41cc2aba37543f34409c43e617651ad1a27bc6c3

commit 41cc2aba37543f34409c43e617651ad1a27bc6c3
Author: Roland Mas <lolando at debian.org>
Date:   Tue Dec 13 11:24:13 2016 +0100

    Implement repositoryList for scmgit (with test)
    
    The softwareheritage_repositoryList SOAP method is now implemented for
    Git.  It returns the primary repository, the secondary repositories,
    and the users' repositories.  The returned URLs depend on the
    permissions of the currently logged-in user, and include the anonymous
    access URL as well as the authenticated access URLs when relevant.

diff --git a/src/plugins/scmgit/common/GitPlugin.class.php b/src/plugins/scmgit/common/GitPlugin.class.php
index 9aebd16..9e82c92 100644
--- a/src/plugins/scmgit/common/GitPlugin.class.php
+++ b/src/plugins/scmgit/common/GitPlugin.class.php
@@ -53,6 +53,7 @@ control over it to the project's administrator.");
 		$this->_addHook('scm_admin_form');
 		$this->_addHook('scm_add_repo');
 		$this->_addHook('scm_delete_repo');
+		$this->_addHook('get_scm_repo_list');
 		$this->_addHook('widget_instance', 'myPageBox', false);
 		$this->_addHook('widgets', 'widgets', false);
 		$this->_addHook('activity');
@@ -1246,6 +1247,104 @@ control over it to the project's administrator.");
 		}
 		return $commits;
 	}
+
+
+    function get_scm_repo_list(&$params) {
+		$protocol = forge_get_config('use_ssl', 'scmgit')? 'https' : 'http';
+		if (session_loggedin()) {
+			$u = user_get_object(user_getid());
+			$d = $u->getUnixName();
+		}
+		
+		$results = array();
+		$res = db_query_params("SELECT unix_group_name, groups.group_id FROM groups
+			JOIN group_plugin ON (groups.group_id=group_plugin.group_id)
+			WHERE groups.status=$1 AND group_plugin.plugin_id=$2
+			ORDER BY unix_group_name", array('A', $this->getID()));
+		while ($arr = db_fetch_array($res)) {
+			if (!forge_check_perm('scm', $arr['group_id'], 'read')) {
+				continue;
+			}
+			$urls = array();
+			if (forge_get_config('use_smarthttp', 'scmgit')) {
+				$urls[] = $protocol.'://'.forge_get_config('scm_host').'/anonscm/git/'.$arr['unix_group_name'].'/'.$arr['unix_group_name'].'.git';
+			}
+			if (session_loggedin()) {
+				if (forge_get_config('use_ssh', 'scmgit')) {
+					$urls[] = 'git+ssh://'.$d.'@' . forge_get_config('scm_host') . forge_get_config('repos_path', 'scmgit') .'/'. $arr['unix_group_name'] .'/'. $arr['unix_group_name'] .'.git';
+				}
+				if (forge_get_config('use_smarthttp', 'scmgit')) {
+					$urls[] = $protocol.'://'.$d.'@'.forge_get_config('scm_host').'/authscm/'.$d.'/git/'.$arr['unix_group_name'].'/'.$arr['unix_group_name'].'.git';
+				}
+			}
+			$results[] = array('group_id' => $arr['group_id'],
+							   'repository_type' => 'git',
+							   'repository_id' => $arr['unix_group_name'].'/git/'.$arr['unix_group_name'],
+							   'repository_urls' => $urls,
+				);
+		}
+		$res = db_query_params("SELECT unix_group_name, groups.group_id, repo_name
+			FROM groups
+			JOIN group_plugin ON (groups.group_id=group_plugin.group_id)
+			JOIN scm_secondary_repos ON (groups.group_id=scm_secondary_repos.group_id)
+			WHERE groups.status=$1 AND group_plugin.plugin_id=$2
+			ORDER BY unix_group_name, repo_name", array('A', $this->getID()));
+		while ($arr = db_fetch_array($res)) {
+			if (!forge_check_perm('scm', $arr['group_id'], 'read')) {
+				continue;
+			}
+			$urls = array();
+			if (forge_get_config('use_smarthttp', 'scmgit')) {
+				$urls[] = $protocol.'://'.forge_get_config('scm_host').'/anonscm/git/'.$arr['unix_group_name'].'/'.$arr['repo_name'].'.git';
+			}
+			if (session_loggedin()) {
+				if (forge_get_config('use_ssh', 'scmgit')) {
+					$urls[] = 'git+ssh://'.$d.'@' . forge_get_config('scm_host') . forge_get_config('repos_path', 'scmgit') .'/'. $arr['unix_group_name'] .'/'. $arr['repo_name'] .'.git';
+				}
+				if (forge_get_config('use_smarthttp', 'scmgit')) {
+					$urls[] = $protocol.'://'.$d.'@'.forge_get_config('scm_host').'/authscm/'.$d.'/git/'.$arr['unix_group_name'].'/'.$arr['repo_name'].'.git';
+				}
+			}
+			$results[] = array('group_id' => $arr['group_id'],
+							   'repository_type' => 'git',
+							   'repository_id' => $arr['unix_group_name'].'/git/'.$arr['repo_name'],
+							   'repository_urls' => $urls,
+				);
+		}
+		$res = db_query_params("SELECT unix_group_name, groups.group_id, user_name
+			FROM groups
+			JOIN group_plugin ON (groups.group_id=group_plugin.group_id)
+			JOIN scm_personal_repos ON (groups.group_id=scm_personal_repos.group_id)
+			JOIN users ON (scm_personal_repos.user_id=users.user_id)
+			WHERE groups.status=$1 AND group_plugin.plugin_id=$2 AND users.status=$3
+			ORDER BY unix_group_name, user_name", array('A', $this->getID(), 'A'));
+		while ($arr = db_fetch_array($res)) {
+			if (!forge_check_perm('scm', $arr['group_id'], 'read')) {
+				continue;
+			}
+			$urls = array();
+			if (forge_get_config('use_smarthttp', 'scmgit')) {
+				$urls[] = $protocol.'://'.forge_get_config('scm_host').'/anonscm/git/'.$arr['unix_group_name'].'/users/'.$arr['user_name'].'.git';
+			}
+			if (session_loggedin()) {
+				if (forge_get_config('use_ssh', 'scmgit')) {
+					$urls[] = 'git+ssh://'.$d.'@' . forge_get_config('scm_host') . forge_get_config('repos_path', 'scmgit') .'/'. $arr['unix_group_name'] .'/users/'. $arr['user_name'] .'.git';
+				}
+				if (forge_get_config('use_smarthttp', 'scmgit')) {
+					$urls[] = $protocol.'://'.$d.'@'.forge_get_config('scm_host').'/authscm/'.$d.'/git/'.$arr['unix_group_name'].'/users/'.$arr['user_name'].'.git';
+				}
+			}
+			$results[] = array('group_id' => $arr['group_id'],
+							   'repository_type' => 'git',
+							   'repository_id' => $arr['unix_group_name'].'/git/users/'.$arr['user_name'],
+							   'repository_urls' => $urls,
+				);
+		}
+
+		foreach ($results as $res) {
+			$params['results'][] = $res;
+		}
+	}
 }
 
 // Local Variables:
diff --git a/src/plugins/softwareheritage/include/softwareheritagePlugin.class.php b/src/plugins/softwareheritage/include/softwareheritagePlugin.class.php
index c83ab05..258e145 100644
--- a/src/plugins/softwareheritage/include/softwareheritagePlugin.class.php
+++ b/src/plugins/softwareheritage/include/softwareheritagePlugin.class.php
@@ -26,6 +26,7 @@ class softwareheritagePlugin extends Plugin {
 		$this->Plugin($id) ;
 		$this->name = "softwareheritage";
 		$this->text = "Software Heritage"; // To show in the tabs, use...
+		$this->_addHook('register_soap');
 	}
 
 	public function register_soap(&$params) {
@@ -33,79 +34,57 @@ class softwareheritagePlugin extends Plugin {
 		$uri = 'http://'.forge_get_config('web_host');
 
 		$server->wsdl->addComplexType(
-			'SoftwareheritageEntry',
+			'SoftwareheritageRepositoryInfo',
 			'complexType',
 			'struct',
 			'sequence',
 			'',
 			array(
 				'group_id' => array('name'=>'group_id', 'type' => 'xsd:int'),
-				'section' => array('name'=>'section', 'type' => 'xsd:string'),
-				'ref_id' => array('name'=>'ref_id', 'type' => 'xsd:string'),
-				'subref_id' => array('name'=>'subref_id', 'type' => 'xsd:string'),
-				'description' => array('name'=>'description', 'type' => 'xsd:string'),
-				'activity_date' => array('name'=>'activity_date', 'type' => 'xsd:int')
+				'repository_id' => array('name'=>'repository_id', 'type' => 'xsd:string'),
+				'repository_urls' => array('name'=>'repository_urls', 'type' => 'tns:ArrayOfstring'),
+				'repository_type' => array('name'=>'repository_type', 'type' => 'xsd:string'),
 				)
 			);
 
 		$server->wsdl->addComplexType(
-			'ArrayOfSoftwareheritageEntry',
+			'ArrayOfSoftwareheritageRepositoryInfo',
 			'complexType',
 			'array',
 			'',
 			'SOAP-ENC:Array',
 			array(),
-			array(array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'tns:SoftwareheritageEntry[]')),
-			'tns:SoftwareheritageEntry');
+			array(array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'tns:SoftwareheritageRepositoryInfo[]')),
+			'tns:SoftwareheritageRepositoryInfo');
                
 		$server->register(
-			'softwareheritage_getActivity',
-			array('session_ser'=>'xsd:string',
-				  'begin'=>'xsd:int',
-				  'end'=>'xsd:int',
-				  'show'=>'tns:ArrayOfstring',),
-			array('return'=>'tns:ArrayOfSoftwareheritageEntry'),
+			'softwareheritage_repositoryList',
+			array('session_ser'=>'xsd:string'),
+			array('return'=>'tns:ArrayOfSoftwareheritageRepositoryInfo'),
 			$uri,
-                       $uri.'#softwareheritage_getActivity','rpc','encoded');
+                       $uri.'#softwareheritage_repositoryList','rpc','encoded');
 	}
 
 
-	function &softwareheritage_getActivity($session_ser,$begin,$end,$show=array()) {
-		continue_session($session_ser);
-
-		$plugin = plugin_get_object('softwareheritage');
-		if (!forge_get_config('use_activity')
-			|| !$plugin) {
-			return new soap_fault ('','softwareheritage_getActivity','Software Heritage not available','Software Heritage not available');
-		}
+}
 
-		$ids = array();
-		$texts = array();
-       
-		$results = $plugin->getData($begin,$end,$show,$ids,$texts);
+function &softwareheritage_repositoryList($session_ser) {
+	continue_session($session_ser);
 
-		$keys = array(
-			'group_id',
-			'section',
-			'ref_id',
-			'subref_id',
-			'description',
-			'activity_date',
-			);
+	$results = array();
+	$params['results'] = &$results;
+	plugin_hook('get_scm_repo_list',$params);
 
+	error_log(print_r($params,true));
 
-		$res2 = array();
-		foreach ($results as $res) {
-			$r = array();
-               
-			foreach ($keys as $k) {
-				$r[$k] = $res[$k];
-			}
-			$res2[] = $r;
+	$res2 = array();
+	foreach ($results as $res) {
+		if (forge_check_perm('scm',$res['group_id'],'read')) {
+			$res2[] = $res;
 		}
-
-		return $res2;
 	}
+
+	return $res2;
 }
 
 // Local Variables:
diff --git a/tests/func/60_PluginsSoftwareHeritage/softwareheritageTest.php b/tests/func/60_PluginsSoftwareHeritage/softwareheritageTest.php
new file mode 100644
index 0000000..36c0eca
--- /dev/null
+++ b/tests/func/60_PluginsSoftwareHeritage/softwareheritageTest.php
@@ -0,0 +1,99 @@
+<?php
+/**
+ * Copyright 2011, Roland Mas
+ * Copyright 2013, Franck Villaume - TrivialDev
+ * Copyright (C) 2015  Inria (Sylvain Beucler)
+ *
+ * This file is part of FusionForge.
+ *
+ * FusionForge 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 2 of the License,
+ * or (at your option) any later version.
+ *
+ * FusionForge 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, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+require_once dirname(dirname(__FILE__)).'/SeleniumForge.php';
+
+class SoftwareHeritage extends FForge_SeleniumTestCase
+{
+	public $fixture = 'projecta';
+
+	function testSoftwareHeritage()
+	{
+		$this->loadAndCacheFixture();
+
+		$this->activatePlugin('softwareheritage');
+		$this->activatePlugin('scmgit');
+
+		$this->open(ROOT);
+		$this->clickAndWait("link=ProjectA");
+		$this->clickAndWait("link=Admin");
+		$this->clickAndWait("link=Tools");
+		$this->clickAndWait("link=Source Code Admin");
+		$this->check("//input[@name='scmengine[]' and @value='scmgit']");
+		$this->clickAndWait("submit");
+
+		$this->type("//input[@name='repo_name']", "other-repo");
+		$this->type("//input[@name='description']", "Description for second repository");
+		$this->clickAndWait("//input[@value='Submit']");
+		$this->assertTextPresent("New repository other-repo registered");
+
+		$this->open(ROOT);
+		$this->clickAndWait("link=ProjectA");
+		$this->clickAndWait("link=SCM");
+		$this->assertTextPresent("other-repo");
+
+		$this->assertTextPresent("Anonymous Access");
+		$this->clickAndWait("link=Request a personal repository");
+		$this->assertTextPresent("You have now requested a personal Git repository");
+
+		// Run the cronjob to create repositories
+		$this->waitSystasks();
+
+
+		// Check SOAP
+
+		$soapclient = new SoapClient(WSDL_URL,
+		array('cache_wsdl' => WSDL_CACHE_NONE,
+		'trace' => true));
+		$this->assertNotNull($soapclient);
+		
+		$userid = FORGE_ADMIN_USERNAME;
+		$passwd = FORGE_ADMIN_PASSWORD;
+		
+		$response = $soapclient->login($userid, $passwd);
+		$session = $response;
+		$this->assertNotEquals($session,"");
+
+		// Get repository list as admin
+		$response = $soapclient->softwareheritage_repositoryList($session);
+		$repos = array();
+		foreach ($response as $data) {
+			$repos[$data->repository_id] = $data;
+		}
+		$this->assertTrue(array_key_exists('projecta/git/projecta',$repos));
+		$this->assertEquals(3,count($repos['projecta/git/projecta']->repository_urls));
+		$this->assertTrue(array_key_exists('projecta/git/other-repo',$repos));
+		$this->assertTrue(array_key_exists('projecta/git/users/admin',$repos));
+
+		// Get repository list as anonymous
+		$response = $soapclient->softwareheritage_repositoryList('');
+		$repos = array();
+		foreach ($response as $data) {
+			$repos[$data->repository_id] = $data;
+		}
+		$this->assertTrue(array_key_exists('projecta/git/projecta',$repos));
+		$this->assertEquals(1,count($repos['projecta/git/projecta']->repository_urls));
+		$this->assertTrue(array_key_exists('projecta/git/other-repo',$repos));
+		$this->assertTrue(array_key_exists('projecta/git/users/admin',$repos));
+	}
+}

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=6e525dab3bcd0ca8a39d8e022c30a7daefe458d0

commit 6e525dab3bcd0ca8a39d8e022c30a7daefe458d0
Author: Roland Mas <lolando at debian.org>
Date:   Mon Dec 12 15:12:02 2016 +0100

    Started Software Heritage plugin

diff --git a/autoinstall/install-src.sh b/autoinstall/install-src.sh
index 3dac20b..63f10a7 100755
--- a/autoinstall/install-src.sh
+++ b/autoinstall/install-src.sh
@@ -56,6 +56,7 @@ fi
     make install-base install-shell install-scm \
         install-plugin-scmcvs install-plugin-scmsvn install-plugin-scmgit \
         install-plugin-blocks install-plugin-moinmoin \
-        install-plugin-online_help install-plugin-taskboard install-plugin-message
+        install-plugin-online_help install-plugin-taskboard install-plugin-message \
+	install-plugin-softwareheritage
     make post-install
 )
diff --git a/autoinstall/install.sh b/autoinstall/install.sh
index 1156123..205e895 100755
--- a/autoinstall/install.sh
+++ b/autoinstall/install.sh
@@ -43,6 +43,7 @@ if [ -e /etc/debian_version ]; then
 	    fusionforge-plugin-scmcvs fusionforge-plugin-scmsvn fusionforge-plugin-scmgit fusionforge-plugin-scmbzr \
 	    fusionforge-plugin-moinmoin \
 	    fusionforge-plugin-blocks fusionforge-plugin-taskboard \
+	    fusionforge-plugin-message fusionforge-plugin-softwareheritage
 	    fusionforge-plugin-message
 	$APT install dpkg-dev
 	if ! dpkg-vendor --is Ubuntu; then
@@ -59,6 +60,6 @@ else
 	yum --enablerepo=epel install -y fusionforge fusionforge-shell fusionforge-scm \
 	    fusionforge-plugin-scmcvs fusionforge-plugin-scmsvn fusionforge-plugin-scmgit \
 	    fusionforge-plugin-blocks fusionforge-plugin-online_help fusionforge-plugin-taskboard \
-	    fusionforge-plugin-message
+	    fusionforge-plugin-message fusionforge-plugin-globalactivity
     fi
 fi
diff --git a/src/debian/plugins b/src/debian/plugins
index 3c88b8a..b637241 100644
--- a/src/debian/plugins
+++ b/src/debian/plugins
@@ -88,6 +88,9 @@ Depends:
 Package: fusionforge-plugin-scmhook
 Depends: php-cli | php5-cli, php-curl | php5-curl, mksh, ${perl:Depends}
 
+Package: fusionforge-plugin-softwareheritage
+Depends:
+
 Package: fusionforge-plugin-sysauthldap
 Depends: php-ldap | php5-ldap
 Recommends: slapd, ldap-utils, ${perl:Depends}
diff --git a/src/plugins/softwareheritage/INSTALL b/src/plugins/softwareheritage/INSTALL
new file mode 100644
index 0000000..a3d0dc2
--- /dev/null
+++ b/src/plugins/softwareheritage/INSTALL
@@ -0,0 +1,13 @@
+0. INSTALLATION of Softwareheritage Plugin
+
+i.e. : if the directory where the plugins are is  /srv/www/gforge/plugins you should end up 
+	with /srv/www/gforge/plugins/softwareheritage and all the files in it
+
+1. CONFIGURATION
+
+A) Make the symbolic links for each section
+
+(this is just an example, you should change the variables for what you have on your installation)
+
+/$GFORGEDIR/www/plugins/softwareheritage -> /$GFORGEPLUGINSDIR/softwareheritage/www
+/$ETC/gforge ->  /$GFORGEPLUGINSDIR/softwareheritage/etc/plugins/softwareheritage
diff --git a/src/plugins/softwareheritage/README b/src/plugins/softwareheritage/README
new file mode 100644
index 0000000..96617ee
--- /dev/null
+++ b/src/plugins/softwareheritage/README
@@ -0,0 +1 @@
+Software Heritage plugin
\ No newline at end of file
diff --git a/src/plugins/softwareheritage/common/softwareheritage-init.php b/src/plugins/softwareheritage/common/softwareheritage-init.php
new file mode 100644
index 0000000..d38dc79
--- /dev/null
+++ b/src/plugins/softwareheritage/common/softwareheritage-init.php
@@ -0,0 +1,32 @@
+<?php
+
+/**
+ *
+ * This file is part of FusionForge.
+ *
+ * FusionForge 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * FusionForge 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, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+global $gfplugins;
+require_once $gfplugins.'softwareheritage/include/softwareheritagePlugin.class.php' ;
+
+$softwareheritagePluginObject = new softwareheritagePlugin ;
+
+register_plugin ($softwareheritagePluginObject) ;
+
+// Local Variables:
+// mode: php
+// c-file-style: "bsd"
+// End:
diff --git a/src/plugins/softwareheritage/etc/softwareheritage.ini b/src/plugins/softwareheritage/etc/softwareheritage.ini
new file mode 100644
index 0000000..74f2636
--- /dev/null
+++ b/src/plugins/softwareheritage/etc/softwareheritage.ini
@@ -0,0 +1,7 @@
+[softwareheritage]
+
+; plugin_status is a string.
+; valid means : production ready.
+; Any other strings means it's under work or broken and plugin
+; is available in installation_environment = development only.
+plugin_status = 'valid'
diff --git a/src/plugins/softwareheritage/include/SoftwareheritagePluginDescriptor.class.php b/src/plugins/softwareheritage/include/SoftwareheritagePluginDescriptor.class.php
new file mode 100644
index 0000000..2d8c51a
--- /dev/null
+++ b/src/plugins/softwareheritage/include/SoftwareheritagePluginDescriptor.class.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * Copyright (c) Xerox Corporation, Codendi Team, 2001-2009. All rights reserved
+ *
+ * This file is a part of Codendi.
+ *
+ * Codendi 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Codendi 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 Codendi. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Portions Copyright 2010 (c) Mélanie Le Bail
+ * Portions Copyright 2011 (c) France Telecom, Coclico project
+ */
+
+require_once 'common/plugin/PluginDescriptor.class.php';
+
+class SoftwareheritagePluginDescriptor extends PluginDescriptor {
+
+    function SoftwareheritagePluginDescriptor() {
+        $this->PluginDescriptor(_('Softwareheritage'), 'v1.0', _('Metadata retrieval API for Software Heritage'));
+    }
+}
diff --git a/src/plugins/softwareheritage/include/SoftwareheritagePluginInfo.class.php b/src/plugins/softwareheritage/include/SoftwareheritagePluginInfo.class.php
new file mode 100644
index 0000000..ff3c512
--- /dev/null
+++ b/src/plugins/softwareheritage/include/SoftwareheritagePluginInfo.class.php
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Copyright (c) Xerox Corporation, Codendi Team, 2001-2009. All rights reserved
+ *
+ * This file is a part of Codendi.
+ *
+ * Codendi 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Codendi 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 Codendi. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright 2010 (c) Mélanie Le Bail
+ * Copyright 2011 (c) France Telecom, Coclico project
+ */
+require_once 'common/plugin/PluginInfo.class.php';
+require_once 'SoftwareheritagePluginDescriptor.class.php';
+
+class SoftwareheritagePluginInfo extends PluginInfo {
+
+    function SoftwareheritagePluginInfo(&$plugin) {
+        $this->PluginInfo($plugin);
+        $this->setPluginDescriptor(new SoftwareheritagePluginDescriptor());
+    }
+
+}
diff --git a/src/plugins/softwareheritage/include/softwareheritagePlugin.class.php b/src/plugins/softwareheritage/include/softwareheritagePlugin.class.php
new file mode 100644
index 0000000..c83ab05
--- /dev/null
+++ b/src/plugins/softwareheritage/include/softwareheritagePlugin.class.php
@@ -0,0 +1,114 @@
+<?php
+
+/**
+ * softwareheritagePlugin Class
+ *
+ *
+ * This file is part of FusionForge.
+ *
+ * FusionForge 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * FusionForge 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, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+class softwareheritagePlugin extends Plugin {
+	public function __construct($id=0) {
+		$this->Plugin($id) ;
+		$this->name = "softwareheritage";
+		$this->text = "Software Heritage"; // To show in the tabs, use...
+	}
+
+	public function register_soap(&$params) {
+		$server = &$params['server'];
+		$uri = 'http://'.forge_get_config('web_host');
+
+		$server->wsdl->addComplexType(
+			'SoftwareheritageEntry',
+			'complexType',
+			'struct',
+			'sequence',
+			'',
+			array(
+				'group_id' => array('name'=>'group_id', 'type' => 'xsd:int'),
+				'section' => array('name'=>'section', 'type' => 'xsd:string'),
+				'ref_id' => array('name'=>'ref_id', 'type' => 'xsd:string'),
+				'subref_id' => array('name'=>'subref_id', 'type' => 'xsd:string'),
+				'description' => array('name'=>'description', 'type' => 'xsd:string'),
+				'activity_date' => array('name'=>'activity_date', 'type' => 'xsd:int')
+				)
+			);
+
+		$server->wsdl->addComplexType(
+			'ArrayOfSoftwareheritageEntry',
+			'complexType',
+			'array',
+			'',
+			'SOAP-ENC:Array',
+			array(),
+			array(array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'tns:SoftwareheritageEntry[]')),
+			'tns:SoftwareheritageEntry');
+               
+		$server->register(
+			'softwareheritage_getActivity',
+			array('session_ser'=>'xsd:string',
+				  'begin'=>'xsd:int',
+				  'end'=>'xsd:int',
+				  'show'=>'tns:ArrayOfstring',),
+			array('return'=>'tns:ArrayOfSoftwareheritageEntry'),
+			$uri,
+                       $uri.'#softwareheritage_getActivity','rpc','encoded');
+	}
+
+
+	function &softwareheritage_getActivity($session_ser,$begin,$end,$show=array()) {
+		continue_session($session_ser);
+
+		$plugin = plugin_get_object('softwareheritage');
+		if (!forge_get_config('use_activity')
+			|| !$plugin) {
+			return new soap_fault ('','softwareheritage_getActivity','Software Heritage not available','Software Heritage not available');
+		}
+
+		$ids = array();
+		$texts = array();
+       
+		$results = $plugin->getData($begin,$end,$show,$ids,$texts);
+
+		$keys = array(
+			'group_id',
+			'section',
+			'ref_id',
+			'subref_id',
+			'description',
+			'activity_date',
+			);
+
+
+		$res2 = array();
+		foreach ($results as $res) {
+			$r = array();
+               
+			foreach ($keys as $k) {
+				$r[$k] = $res[$k];
+			}
+			$res2[] = $r;
+		}
+
+		return $res2;
+	}
+}
+
+// Local Variables:
+// mode: php
+// c-file-style: "bsd"
+// End:

https://scm.fusionforge.org/anonscm/gitweb/?p=fusionforge/fusionforge.git;a=commitdiff;h=80151b50c4cbf57ebe52dbdffe09567d4379f973

commit 80151b50c4cbf57ebe52dbdffe09567d4379f973
Author: Roland Mas <lolando at debian.org>
Date:   Tue May 31 13:47:57 2016 +0200

    New hook to allow plugins to register SOAP methods

diff --git a/src/www/soap/index.php b/src/www/soap/index.php
index 8ffe50d..99c4e67 100644
--- a/src/www/soap/index.php
+++ b/src/www/soap/index.php
@@ -128,6 +128,11 @@ require_once $gfwww.'soap/frs/frs.php';
 //
 require_once $gfwww.'soap/scm/scm.php';
 
+// Include methods defined by plugins
+$params = array();
+$params['server'] = &$server;
+plugin_hook('register_soap',$params);
+
 $wsdl_data = $server->wsdl->serialize();
 
 if (isset($wsdl)) {

-----------------------------------------------------------------------


hooks/post-receive
-- 
FusionForge



More information about the Fusionforge-commits mailing list