[Fusionforge-commits] FusionForge branch master updated. c1a99e86f770472b8d4400fdd43cb797b9ba7259

Franck VILLAUME nerville at fusionforge.org
Sat Feb 22 23:27:16 CET 2014


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, master has been updated
       via  c1a99e86f770472b8d4400fdd43cb797b9ba7259 (commit)
       via  6b46085e08ce2a2d917f271db486a809505d5ea6 (commit)
      from  b0e2ab6adfd01cf36d428580afc0b793d51019f4 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit c1a99e86f770472b8d4400fdd43cb797b9ba7259
Author: Franck Villaume <franck.villaume at trivialdev.com>
Date:   Sat Feb 22 23:25:31 2014 +0100

    feature request [#635]: link a document from docman into a FRSRelease

diff --git a/src/common/docman/DocumentManager.class.php b/src/common/docman/DocumentManager.class.php
index ac008d8..93148a1 100644
--- a/src/common/docman/DocumentManager.class.php
+++ b/src/common/docman/DocumentManager.class.php
@@ -26,6 +26,7 @@
 require_once $gfcommon.'include/Error.class.php';
 require_once $gfcommon.'include/User.class.php';
 require_once $gfcommon.'docman/DocumentGroup.class.php';
+require_once $gfcommon.'docman/DocumentFactory.class.php';
 
 class DocumentManager extends Error {
 
@@ -284,9 +285,10 @@ class DocumentManager extends Error {
 	 * @param	bool	$allow_none	Allow selection of "None"
 	 * @param	int	$selected_id	The ID of the group that should be selected by default (if any)
 	 * @param	array	$dont_display	Array of IDs of groups that should not be displayed
+	 * @param	bool	$display_files	Display filename instead of directory name only.
 	 * @return	string	html select box code
 	 */
-	function showSelectNestedGroups($group_arr, $select_name, $allow_none = true, $selected_id = 0, $dont_display = array()) {
+	function showSelectNestedGroups($group_arr, $select_name, $allow_none = true, $selected_id = 0, $dont_display = array(), $display_files = false) {
 		// Build arrays for calling html_build_select_box_from_arrays()
 		$id_array = array();
 		$text_array = array();
@@ -298,7 +300,7 @@ class DocumentManager extends Error {
 		}
 
 		// Recursively build the document group tree
-		$this->buildArrays($group_arr, $id_array, $text_array, $dont_display);
+		$this->buildArrays($group_arr, $id_array, $text_array, $dont_display, 0, 0, $display_files);
 
 		echo html_build_select_box_from_arrays($id_array, $text_array, $select_name, $selected_id, false);
 	}
@@ -310,10 +312,11 @@ class DocumentManager extends Error {
 	 * @param	array	$id_array	Reference to the array of ids that will be build
 	 * @param	array	$text_array	Reference to the array of group names
 	 * @param	array	$dont_display	Array of IDs of groups that should not be displayed
-	 * @param	int	$parent	The ID of the parent whose childs are being showed (0 for root groups)
-	 * @param	int	$level	The current level
+	 * @param	int	$parent		The ID of the parent whose childs are being showed (0 for root groups)
+	 * @param	int	$level		The current level
+	 * @param	bool	$display_files	Set filename instead of directory name.
 	 */
-	function buildArrays($group_arr, &$id_array, &$text_array, &$dont_display, $parent = 0, $level = 0) {
+	function buildArrays($group_arr, &$id_array, &$text_array, &$dont_display, $parent = 0, $level = 0, $display_files = false) {
 		if (!is_array($group_arr) || !array_key_exists("$parent", $group_arr)) return;
 
 		$child_count = count($group_arr["$parent"]);
@@ -325,11 +328,20 @@ class DocumentManager extends Error {
 
 			$margin = str_repeat("--", $level);
 
-			$id_array[] = $doc_group->getID();
-			$text_array[] = $margin.$doc_group->getName();
-
+			if (!$display_files) {
+				$id_array[] = $doc_group->getID();
+				$text_array[] = $margin.$doc_group->getName();
+			} else {
+				$df = new DocumentFactory($doc_group->getGroup());
+				$df->setDocGroupID($doc_group->getID());
+				$docs = $df->getDocuments();
+				foreach ($docs as $doc) {
+					$id_array[] = $doc->getID();
+					$text_array[] = $margin.$doc_group->getName().'/'.$doc->getFileName();
+				}
+			}
 			// Show childs (if any)
-			$this->buildArrays($group_arr, $id_array, $text_array, $dont_display, $doc_group->getID(), $level+1);
+			$this->buildArrays($group_arr, $id_array, $text_array, $dont_display, $doc_group->getID(), $level+1, $display_files);
 		}
 	}
 
diff --git a/src/common/frs/FRSFile.class.php b/src/common/frs/FRSFile.class.php
index b862a9b..95fe16d 100644
--- a/src/common/frs/FRSFile.class.php
+++ b/src/common/frs/FRSFile.class.php
@@ -132,7 +132,7 @@ class FRSFile extends Error {
 		//	before calling this function
 		//
 		if (!is_file($file_location) || !file_exists($file_location)) {
-			$this->setError(_('FRSFile Appears to be invalid'));
+			$this->setError(_('FRSFile appears to be invalid.'));
 			return false;
 		}
 
diff --git a/src/common/frs/include/frs_utils.php b/src/common/frs/include/frs_utils.php
index 577efdf..c6233e2 100644
--- a/src/common/frs/include/frs_utils.php
+++ b/src/common/frs/include/frs_utils.php
@@ -6,7 +6,7 @@
  * Copyright 2002-2004 (c) GForge Team
  * Copyright (C) 2011 Alain Peyrat - Alcatel-Lucent
  * Copyright 2011, Franck Villaume - Capgemini
- * Copyright 2013, Franck Villaume - TrivialDev
+ * Copyright 2013-2014, Franck Villaume - TrivialDev
  * http://fusionforge.org/
  *
  * This file is part of FusionForge. FusionForge is free software;
@@ -206,10 +206,10 @@ function frs_show_package_popup ($group_id, $name='package_id', $checked_val="xz
 }
 
 function frs_add_file_from_form ($release, $type_id, $processor_id, $release_date,
-				 $userfile, $ftp_filename, $manual_filename) {
+				 $userfile, $ftp_filename, $manual_filename, $docman_fileid) {
 
-	$group_unix_name = $release->getFRSPackage()->getGroup()->getUnixName() ;
-	$incoming = forge_get_config('groupdir_prefix')."/$group_unix_name/incoming" ;
+	$group_unix_name = $release->getFRSPackage()->getGroup()->getUnixName();
+	$incoming = forge_get_config('groupdir_prefix').'/'.$group_unix_name.'/incoming';
 
 	$filechecks = false ;
 
@@ -241,6 +241,12 @@ function frs_add_file_from_form ($release, $type_id, $processor_id, $release_dat
 		$fname = $manual_filename ;
 		$move = false ;
 		$filechecks = true ;
+	} elseif ($release->getFRSPackage()->getGroup()->usesDocman() && $docman_fileid) {
+		$doc = new Document($release->getFRSPackage()->getGroup(), $docman_fileid);
+		$fname = $doc->getFilename();
+		$infile = DocumentStorage::instance()->get($docman_fileid);
+		$move = false;
+		$filechecks = true;
 	} elseif ($userfile && $userfile['error'] == UPLOAD_ERR_NO_FILE) {
 		return _('Must select a file.') ;
 	}
diff --git a/src/www/frs/admin/editrelease.php b/src/www/frs/admin/editrelease.php
index 4c7ddf8..b0e277a 100644
--- a/src/www/frs/admin/editrelease.php
+++ b/src/www/frs/admin/editrelease.php
@@ -29,6 +29,7 @@ require_once $gfcommon.'frs/FRSPackage.class.php';
 require_once $gfcommon.'frs/FRSRelease.class.php';
 require_once $gfcommon.'frs/FRSFile.class.php';
 require_once $gfcommon.'frs/include/frs_utils.php';
+require_once $gfcommon.'docman/DocumentManager.class.php';
 
 $group_id = getIntFromRequest('group_id');
 $package_id = getIntFromRequest('package_id');
@@ -149,9 +150,10 @@ if (getStringFromRequest('step2')) {
 	$group_unix_name=group_getunixname($group_id);
 	$ftp_filename = getStringFromRequest('ftp_filename');
 	$manual_filename = getStringFromRequest('manual_filename');
+	$docman_fileid = getIntFromRequest('docman_fileid');
 
-	$ret = frs_add_file_from_form ($frsr, $type_id, $processor_id, $release_date,
-				       $userfile, $ftp_filename, $manual_filename) ;
+	$ret = frs_add_file_from_form($frsr, $type_id, $processor_id, $release_date,
+				       $userfile, $ftp_filename, $manual_filename, $docman_fileid);
 
 	if ($ret === true) {
 		$feedback = _('File Released') ;
@@ -315,6 +317,12 @@ if (forge_get_config('use_manual_uploads')) {
 	echo html_build_select_box_from_arrays($manual_files_arr,$manual_files_arr,'manual_filename','');
 	echo '</p>';
 }
+if ($group->usesDocman()) {
+	echo html_e('p', array(), _('Alternatively, you can pick a file available in the Documents Management tool.'), false);
+	$dm = new DocumentManager($group);
+	$dgf = new DocumentGroupFactory($group);
+	$dm->showSelectNestedGroups($dgf->getNested(), 'docman_fileid', true, 0, array(), true);
+}
 ?>
 </fieldset>
 <table width="60%">

commit 6b46085e08ce2a2d917f271db486a809505d5ea6
Author: Franck Villaume <franck.villaume at trivialdev.com>
Date:   Sat Feb 22 19:50:42 2014 +0100

    docman: drop obsolete DocumentGroupHTML.class.php

diff --git a/src/common/docman/DocumentManager.class.php b/src/common/docman/DocumentManager.class.php
index 7c24065..ac008d8 100644
--- a/src/common/docman/DocumentManager.class.php
+++ b/src/common/docman/DocumentManager.class.php
@@ -277,6 +277,33 @@ class DocumentManager extends Error {
 	}
 
 	/**
+	 * showSelectNestedGroups - Display the tree of document groups inside a <select> tag
+	 *
+	 * @param	array	$group_arr	Array of groups.
+	 * @param	string	$select_name	The name that will be assigned to the input
+	 * @param	bool	$allow_none	Allow selection of "None"
+	 * @param	int	$selected_id	The ID of the group that should be selected by default (if any)
+	 * @param	array	$dont_display	Array of IDs of groups that should not be displayed
+	 * @return	string	html select box code
+	 */
+	function showSelectNestedGroups($group_arr, $select_name, $allow_none = true, $selected_id = 0, $dont_display = array()) {
+		// Build arrays for calling html_build_select_box_from_arrays()
+		$id_array = array();
+		$text_array = array();
+
+		if ($allow_none) {
+			// First option to be displayed
+			$id_array[] = 0;
+			$text_array[] = _('None');
+		}
+
+		// Recursively build the document group tree
+		$this->buildArrays($group_arr, $id_array, $text_array, $dont_display);
+
+		echo html_build_select_box_from_arrays($id_array, $text_array, $select_name, $selected_id, false);
+	}
+
+	/**
 	 * buildArrays - Build the arrays to call html_build_select_box_from_arrays()
 	 *
 	 * @param	array	$group_arr	Array of groups.
diff --git a/src/common/docman/include/DocumentGroupHTML.class.php b/src/common/docman/include/DocumentGroupHTML.class.php
deleted file mode 100644
index 57bbcc1..0000000
--- a/src/common/docman/include/DocumentGroupHTML.class.php
+++ /dev/null
@@ -1,117 +0,0 @@
-<?php
-/**
- * FusionForge Documentation Manager
- *
- * Copyright 2002 GForge, LLC
- * Copyright 2010, Franck Villaume - Capgemini
- * Copyright (C) 2012 Alain Peyrat - Alcatel-Lucent
- * Copyright 2013-2014 Franck Villaume - TrivialDev
- * http://fusionforge.org
- *
- * 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_once $gfcommon.'include/pre.php';
-require_once $gfwww.'include/note.php';
-
-/**
- * Wrap many group display related functions
- */
-class DocumentGroupHTML extends Error {
-	var $Group;
-
-	/**
-	 * Constructor.
-	 *
-	 * @param	$Group
-	 * @return	\DocumentGroupHTML
-	 */
-	function __construct(&$Group) {
-		$this->Error();
-
-		if (!$Group || !is_object($Group)) {
-			$this->setError(_('No Valid Group Object'));
-			return;
-		}
-		if ($Group->isError()) {
-			$this->setError(_('Error') . _(': ') . $Group->getErrorMessage());
-			return;
-		}
-		$this->Group =& $Group;
-	}
-
-	/**
-	 * showSelectNestedGroups - Display the tree of document groups inside a <select> tag
-	 *
-	 * @param	array	$group_arr	Array of groups.
-	 * @param	string	$select_name	The name that will be assigned to the input
-	 * @param	bool	$allow_none	Allow selection of "None"
-	 * @param	int	$selected_id	The ID of the group that should be selected by default (if any)
-	 * @param	array	$dont_display	Array of IDs of groups that should not be displayed
-	 * @return	string	html select box code
-	 */
-	function showSelectNestedGroups($group_arr, $select_name, $allow_none = true, $selected_id = 0, $dont_display = array()) {
-		// Build arrays for calling html_build_select_box_from_arrays()
-		$id_array = array();
-		$text_array = array();
-
-		if ($allow_none) {
-			// First option to be displayed
-			$id_array[] = 0;
-			$text_array[] = _('None');
-		}
-
-		// Recursively build the document group tree
-		$this->buildArrays($group_arr, $id_array, $text_array, $dont_display);
-
-		echo html_build_select_box_from_arrays($id_array, $text_array, $select_name, $selected_id, false);
-	}
-
-	/**
-	 * buildArrays - Build the arrays to call html_build_select_box_from_arrays()
-	 *
-	 * @param	array	$group_arr	Array of groups.
-	 * @param	array	$id_array	Reference to the array of ids that will be build
-	 * @param	array	$text_array	Reference to the array of group names
-	 * @param	array	$dont_display	Array of IDs of groups that should not be displayed
-	 * @param	int	$parent		The ID of the parent whose childs are being showed (0 for root groups)
-	 * @param	int	$level		The current level
-	 */
-	function buildArrays($group_arr, &$id_array, &$text_array, &$dont_display, $parent = 0, $level = 0) {
-		if (!is_array($group_arr) || !array_key_exists("$parent", $group_arr)) return;
-
-		$child_count = count($group_arr["$parent"]);
-		for ($i = 0; $i < $child_count; $i++) {
-			$doc_group =& $group_arr["$parent"][$i];
-
-			// Should we display this element?
-			if (in_array($doc_group->getID(), $dont_display)) continue;
-
-			$margin = str_repeat("--", $level);
-
-			$id_array[] = $doc_group->getID();
-			$text_array[] = $margin.$doc_group->getName();
-
-			// Show childs (if any)
-			$this->buildArrays($group_arr, $id_array, $text_array, $dont_display, $doc_group->getID(), $level+1);
-		}
-	}
-}
-
-// Local Variables:
-// mode: php
-// c-file-style: "bsd"
-// End:
diff --git a/src/common/docman/views/addfile.php b/src/common/docman/views/addfile.php
index 86ed460..4d9097b 100644
--- a/src/common/docman/views/addfile.php
+++ b/src/common/docman/views/addfile.php
@@ -7,7 +7,7 @@
  * Copyright 2010-2011, Franck Villaume - Capgemini
  * Copyright 2011, Roland Mas
  * Copyright (C) 2011 Alain Peyrat - Alcatel-Lucent
- * Copyright 2012-2013, Franck Villaume - TrivialDev
+ * Copyright 2012-2014, Franck Villaume - TrivialDev
  * http://fusionforge.org
  *
  * This file is part of FusionForge. FusionForge is free software;
@@ -31,6 +31,7 @@
 global $g; // group object
 global $group_id; // id of the group
 global $dirid; //id of the doc_group
+global $dm; // the Document Manager object
 
 // plugin projects-hierarchy
 $actionurl = '?group_id='.$group_id.'&action=addfile&dirid='.$dirid;
@@ -45,10 +46,6 @@ $dgf = new DocumentGroupFactory($g);
 if ($dgf->isError())
 	exit_error($dgf->getErrorMessage(), 'docman');
 
-$dgh = new DocumentGroupHTML($g);
-if ($dgh->isError())
-	exit_error($dgh->getErrorMessage(), 'docman');
-
 if (!forge_check_perm('docman', $group_id, 'submit')) {
 	$return_msg = _('Document Manager Action Denied.');
 	session_redirect($redirecturl.'&warning_msg='.urlencode($return_msg));
@@ -179,7 +176,7 @@ if ($dgf->getNested() == NULL) {
 		echo html_ao('tr');
 		echo html_e('td', array(), _('Documents folder that document belongs in'), false);
 		echo html_ao('td');
-		$dgh->showSelectNestedGroups($dgf->getNested(), 'doc_group', false, $dirid);
+		$dm->showSelectNestedGroups($dgf->getNested(), 'doc_group', false, $dirid);
 		echo html_ac(html_ap() - 2);
 	}
 	if (forge_check_perm('docman', $group_id, 'approve')) {
diff --git a/src/common/docman/views/editdocgroup.php b/src/common/docman/views/editdocgroup.php
index 38457db..b7fcfaa 100644
--- a/src/common/docman/views/editdocgroup.php
+++ b/src/common/docman/views/editdocgroup.php
@@ -7,7 +7,7 @@
  * Copyright 2002-2003, Tim Perdue/GForge, LLC
  * Copyright 2010-2011, Franck Villaume - Capgemini
  * Copyright (C) 2011 Alain Peyrat - Alcatel-Lucent
- * Copyright 2013, Franck Villaume - TrivialDev
+ * Copyright 2013-2014, Franck Villaume - TrivialDev
  * http://fusionforge.org
  *
  * This file is part of FusionForge. FusionForge is free software;
@@ -32,7 +32,7 @@ global $g; //group object
 global $group_id; // id of the group
 global $dirid; // id of doc_group
 global $dgf; // document directory factory of this group
-global $dgh; // document directory html
+global $dm; // the Document Manager object
 
 if (!forge_check_perm('docman', $group_id, 'approve')) {
 	$return_msg= _('Document Manager Access Denied');
@@ -64,10 +64,10 @@ if ($dg->isError())
 <?php
 if ($dg->getState() == 2) {
 	$newdgf = new DocumentGroupFactory($g);
-	$dgh->showSelectNestedGroups($newdgf->getNested(), 'parent_dirid', true, false);
+	$dm->showSelectNestedGroups($newdgf->getNested(), 'parent_dirid', true, false);
 	$labelSubmit = _('Restore');
 } else {
-	$dgh->showSelectNestedGroups($dgf->getNested(), 'parent_dirid', true, $dg->getParentId(), array($dg->getID()));
+	$dm->showSelectNestedGroups($dgf->getNested(), 'parent_dirid', true, $dg->getParentId(), array($dg->getID()));
 	$labelSubmit = _('Edit');
 }
 ?>
diff --git a/src/common/docman/views/listfile.php b/src/common/docman/views/listfile.php
index 05b752d..5b22399 100644
--- a/src/common/docman/views/listfile.php
+++ b/src/common/docman/views/listfile.php
@@ -6,9 +6,8 @@
  * Copyright 2002-2003, Tim Perdue/GForge, LLC
  * Copyright (C) 2010 Alcatel-Lucent
  * Copyright 2010-2011, Franck Villaume - Capgemini
- * Copyright 2012-2013, Franck Villaume - TrivialDev
-
  * Copyright (C) 2011 Alain Peyrat - Alcatel-Lucent
+ * Copyright 2012-2014, Franck Villaume - TrivialDev
  * http://fusionforge.org
  *
  * This file is part of FusionForge. FusionForge is free software;
@@ -69,10 +68,6 @@ $dgf = new DocumentGroupFactory($g);
 if ($dgf->isError())
 	exit_error($dgf->getErrorMessage(), 'docman');
 
-$dgh = new DocumentGroupHTML($g);
-if ($dgh->isError())
-	exit_error($dgh->getErrorMessage(), 'docman');
-
 $df->setDocGroupID($dirid);
 
 $df->setStateID('1');
diff --git a/src/common/docman/views/tree.php b/src/common/docman/views/tree.php
index 291735c..cfe125c 100644
--- a/src/common/docman/views/tree.php
+++ b/src/common/docman/views/tree.php
@@ -6,7 +6,7 @@
  * Copyright 2002-2003, Tim Perdue/GForge, LLC
  * Copyright 2010-2011, Franck Villaume - Capgemini
  * Copyright (C) 2011 Alain Peyrat - Alcatel-Lucent
- * Copyright 2013, Franck Villaume - TrivialDev
+ * Copyright 2013-2014, Franck Villaume - TrivialDev
  * http://fusionforge.org
  *
  * This file is part of FusionForge. FusionForge is free software;
@@ -62,9 +62,9 @@ if (isset($projectIDsArray) && is_array($projectIDsArray)) {
 			&& forge_check_perm('docman', $groupObject->getID(), 'read')) {
 			echo '<hr>';
 			echo '<h5>'._('Child project')._(': ').util_make_link('/docman/?group_id='.$groupObject->getID(),$groupObject->getPublicName(), array('class'=>'tabtitle', 'title'=>_('Browse document manager for this project.'))).'</h5>';
-			$dm = new DocumentManager($groupObject);
+			$dmc = new DocumentManager($groupObject);
 			echo '<ul id="'.$groupObject->getUnixname().'-tree">';
-			$dm->getTree($dirid, $linkmenu);
+			$dmc->getTree($dirid, $linkmenu);
 			echo '</ul>';
 			echo '
 			<script type="text/javascript">//<![CDATA[
diff --git a/src/www/docman/index.php b/src/www/docman/index.php
index 4ead680..131b104 100644
--- a/src/www/docman/index.php
+++ b/src/www/docman/index.php
@@ -6,7 +6,7 @@
  * Copyright 2002-2003, Tim Perdue/GForge, LLC
  * Copyright 2010-2011, Franck Villaume - Capgemini
  * Copyright (C) 2010-2011 Alain Peyrat - Alcatel-Lucent
- * Copyright 2012-2013, Franck Villaume - TrivialDev
+ * Copyright 2012-2014, Franck Villaume - TrivialDev
  * http://fusionforge.org
  *
  * This file is part of FusionForge. FusionForge is free software;
@@ -32,7 +32,6 @@ require_once $gfcommon.'docman/Document.class.php';
 require_once $gfcommon.'docman/DocumentFactory.class.php';
 require_once $gfcommon.'docman/DocumentGroup.class.php';
 require_once $gfcommon.'docman/DocumentGroupFactory.class.php';
-require_once $gfcommon.'docman/include/DocumentGroupHTML.class.php';
 require_once $gfcommon.'docman/include/utils.php';
 require_once $gfcommon.'include/TextSanitizer.class.php'; // to make the HTML input by the user safe to store
 require_once $gfcommon.'reporting/report_utils.php';

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

Summary of changes:
 src/common/docman/DocumentManager.class.php        |   53 +++++++--
 .../docman/include/DocumentGroupHTML.class.php     |  117 --------------------
 src/common/docman/views/addfile.php                |    9 +-
 src/common/docman/views/editdocgroup.php           |    8 +-
 src/common/docman/views/listfile.php               |    7 +-
 src/common/docman/views/tree.php                   |    6 +-
 src/common/frs/FRSFile.class.php                   |    2 +-
 src/common/frs/include/frs_utils.php               |   14 ++-
 src/www/docman/index.php                           |    3 +-
 src/www/frs/admin/editrelease.php                  |   12 +-
 10 files changed, 79 insertions(+), 152 deletions(-)
 delete mode 100644 src/common/docman/include/DocumentGroupHTML.class.php


hooks/post-receive
-- 
FusionForge



More information about the Fusionforge-commits mailing list