[Fusionforge-commits] r11982 - in trunk/src: common/frs www/frs

Roland Mas lolando at libremir.placard.fr.eu.org
Thu Jan 13 17:10:35 CET 2011


Author: lolando
Date: 2011-01-13 17:10:35 +0100 (Thu, 13 Jan 2011)
New Revision: 11982

Modified:
   trunk/src/common/frs/FRSFile.class.php
   trunk/src/common/frs/FRSPackage.class.php
   trunk/src/common/frs/FRSRelease.class.php
   trunk/src/www/frs/download.php
   trunk/src/www/frs/index.php
Log:
FRS: Download latest version of a file from a package, or latest release of a package as a zip

Modified: trunk/src/common/frs/FRSFile.class.php
===================================================================
--- trunk/src/common/frs/FRSFile.class.php	2011-01-13 16:06:28 UTC (rev 11981)
+++ trunk/src/common/frs/FRSFile.class.php	2011-01-13 16:10:35 UTC (rev 11982)
@@ -25,6 +25,33 @@
 
 require_once $gfcommon.'include/Error.class.php';
 
+/**
+ *	  Factory method which creates a FRSFile from an release id
+ *
+ *	  @param int	  The file id
+ *	  @param array	The result array, if it's passed in
+ *	  @return object  FRSFile object
+ */
+function &frsfile_get_object($file_id, $data=false) {
+	global $FRSFILE_OBJ;
+	if (!isset($FRSFILE_OBJ['_'.$file_id.'_'])) {
+		if ($data) {
+					//the db result handle was passed in
+		} else {
+			$res = db_query_params ('SELECT * FROM frs_file WHERE file_id=$1',
+						array ($file_id)) ;
+			if (db_numrows($res)<1 ) {
+				$FRSFILE_OBJ['_'.$file_id.'_']=false;
+				return false;
+			}
+			$data = db_fetch_array($res);
+		}
+		$FRSRelease =& frsrelease_get_object($data['release_id']);
+		$FRSFILE_OBJ['_'.$file_id.'_']= new FRSFile($FRSRelease,$data['file_id'],$data);
+	}
+	return $FRSFILE_OBJ['_'.$file_id.'_'];
+}
+
 class FRSFile extends Error {
 
 	/**
@@ -190,6 +217,7 @@
 			return false;
 		} else {
 			db_commit();
+			$this->FRSRelease->FRSPackage->createNewestReleaseFilesAsZip();
 			return true;
 		}
 	}
@@ -340,6 +368,7 @@
 						array ($this->getID())) ;
 			$res = db_query_params ('DELETE FROM frs_dlstats_filetotal_agg WHERE file_id=$1',
 						array ($this->getID())) ;
+			$this->FRSRelease->FRSPackage->createNewestReleaseFilesAsZip();
 			return true;
 		}
 	}
@@ -417,6 +446,7 @@
 			}
 		}
 		db_commit();
+		$this->FRSRelease->FRSPackage->createNewestReleaseFilesAsZip();
 		return true;
 	}
 }

Modified: trunk/src/common/frs/FRSPackage.class.php
===================================================================
--- trunk/src/common/frs/FRSPackage.class.php	2011-01-13 16:06:28 UTC (rev 11981)
+++ trunk/src/common/frs/FRSPackage.class.php	2011-01-13 16:10:35 UTC (rev 11982)
@@ -45,7 +45,7 @@
  * @param	array	the DB handle if passed in (optional)
  * @return	object	the FRSPackage object
  */
-function &frspackage_get_object($package_id, $data=false) {
+function frspackage_get_object($package_id, $data=false) {
 	global $FRSPACKAGE_OBJ;
 	if (!isset($FRSPACKAGE_OBJ['_'.$package_id.'_'])) {
 		if ($data) {
@@ -54,7 +54,6 @@
 			$res = db_query_params ('SELECT * FROM frs_package WHERE package_id=$1',
 						array ($package_id)) ;
 			if (db_numrows($res)<1) {
-				$FRSPACKAGE_OBJ['_'.$package_id.'_']=false;
 				return false;
 			}
 			$data = db_fetch_array($res);
@@ -416,6 +415,7 @@
 			}
 		}	
 		db_commit();
+		$this->createNewestReleaseFilesAsZip();
 		return true;
 	}
 
@@ -477,6 +477,55 @@
 		return true;
 	}
 
+	/**
+	 *  Function that selects the newest release. 
+	 *  The newest release is the release with the highest ID
+	 * 
+	 *  @return object FRSRelease
+	 */
+	
+	function getNewestRelease() {
+		$result = db_query_params('SELECT MAX(release_id) AS release_id FROM frs_release WHERE package_id=$1',
+					  array ($this->getID())) ;
+		
+		if ($result && db_numrows($result) == 1) {
+			$row = db_fetch_array($result);
+			return frsrelease_get_object($row['release_id']);
+		} else {
+			$this->setError('FRSRelease:: No valid max release id');
+			return false;
+		} 
+	}
+
+	public function getNewestReleaseZipName () {
+		return $this->getFileName()."-latest.zip";
+	}
+
+	public function getNewestReleaseZipPath () {
+		return forge_get_config('upload_dir').'/'.$this->Group->getUnixName().'/'.$this->getFileName().'/'.$this->getNewestReleaseZipName();
+	}
+
+	public function createNewestReleaseFilesAsZip(){
+		$zip = new ZipArchive();
+		$release = $this->getNewestRelease();
+
+		$zipPath = $this->getNewestReleaseZipPath();
+		$filesPath = forge_get_config('upload_dir').'/'.$this->Group->getUnixName().'/'.$this->getFileName().'/'.$release->getFileName();
+
+		if ($zip->open($zipPath, ZIPARCHIVE::OVERWRITE)!==true) {
+			exit_error(_('Cannot open the file archive.').' '.$zipPath.'.');
+		}
+
+		$files = $release->getFiles();
+	
+		foreach ($files as $f) {
+			$filePath = $filesPath.'/'.$f->getName();	
+			$zip->addFile($filePath,$f->getName());
+		} 
+
+		$zip->close();
+	}
+
 }
 
 // Local Variables:

Modified: trunk/src/common/frs/FRSRelease.class.php
===================================================================
--- trunk/src/common/frs/FRSRelease.class.php	2011-01-13 16:06:28 UTC (rev 11981)
+++ trunk/src/common/frs/FRSRelease.class.php	2011-01-13 16:10:35 UTC (rev 11982)
@@ -468,6 +468,7 @@
 			}
 		}	
 		db_commit();
+		$this->FRSPackage->createNewestReleaseFilesAsZip();
 		return true;
 	}
 

Modified: trunk/src/www/frs/download.php
===================================================================
--- trunk/src/www/frs/download.php	2011-01-13 16:06:28 UTC (rev 11981)
+++ trunk/src/www/frs/download.php	2011-01-13 16:10:35 UTC (rev 11982)
@@ -32,88 +32,149 @@
 require_once $gfcommon.'frs/FRSRelease.class.php';
 require_once $gfcommon.'frs/FRSFile.class.php';
 
-$arr=explode('/',getStringFromServer('REQUEST_URI'));
-$file_id=$arr[3];
+/* This script can work in one of the following modes:
+ * - file: one specific file (given its file_id)
+ * - latestzip: gets a Zip archive containing all files in the latest
+ *   release of a given package (given a package_id)
+ * - latestfile: the version of a file that's in the
+ *   latest release of a given package (given the file name and the
+ *   package_id)
+ */
 
-$res=db_query_params ('SELECT frs_file.filename,frs_package.is_public,frs_package.package_id,
-	frs_file.file_id,groups.unix_group_name,groups.group_id,frs_release.release_id
-	FROM frs_package,frs_release,frs_file,groups
-	WHERE frs_release.release_id=frs_file.release_id
-	AND groups.group_id=frs_package.group_id
-	AND frs_release.package_id=frs_package.package_id
-	AND frs_file.file_id=$1',
-			array($file_id));
-
-if (db_numrows($res) < 1) {
+function send_404 () {
+	global $gfwww;
 	header("HTTP/1.0 404 Not Found");
 	require_once $gfwww.'404.php';
 	exit;
 }
 
-$group_id = db_result($res,0,'group_id');
-$package_id = db_result($res,0,'package_id');
-$release_id = db_result($res,0,'release_id');
+function send_file ($filename,$filepath,$file_id=NULL) {
+	if (!file_exists($filepath)) {
+		send_404();
+	}
+	
+	if ($GLOBALS['sys_block_anonymous_downloads']) {
+		if (!session_loggedin()) {
+			exit_permission_denied();
+		}
+	}
 
-$Group =& group_get_object($group_id);
-if (!$Group || !is_object($Group) || $Group->isError()) {
-	exit_no_group();
+	header('Content-disposition: attachment; filename="'.str_replace('"', '', $filename).'"');
+	header("Content-type: application/binary");
+	$length = filesize($filepath);
+	header("Content-length: $length");
+	
+	readfile_chunked($filepath);
+	
+	if (!$file_id) {
+		return true;
+	}
+	
+	if (session_loggedin()) {
+		$s =& session_get_user();
+		$us=$s->getID();
+	} else {
+		$us=100;
+	}
+	
+	$ip = getStringFromServer('REMOTE_ADDR');
+	$res = db_query_params("INSERT INTO frs_dlstats_file (ip_address,file_id,month,day,user_id) VALUES ($1, $2, $3, $4, $5)", array($ip,$file_id,date('Ym'),date('d'),$us));
 }
 
-$Package = new FRSPackage($Group,$package_id);
-if (!$Package || !is_object($Package)) {
-	exit_error(_('Error Getting Package'),'frs');
-} else if ($Package->isError()) {
-	exit_error($Package->getErrorMessage(),'frs');
-}
-$is_public = $Package->isPublic();
+$normalized_urlprefix = normalized_urlprefix();
+$pathinfo = substr_replace(getStringFromServer('REQUEST_URI'), '', 0, strlen($normalized_urlprefix)-1);
+$expl_pathinfo = explode('/', $pathinfo);
 
-$Release = new FRSRelease($Package,$release_id);
-if (!$Release || !is_object($Release) || $Release->isError()) {
-	exit_error(_('Error Getting Release'),'frs');
-}
+$mode = $expl_pathinfo[3];
 
-$File = new FRSFile($Release,$file_id);
-if (!$File || !is_object($File) || $File->isError()) {
-	exit_error(_('Error Getting File'),'frs');
-}
-$filename = $File->getName();
+switch ($mode) {
+case 'file':
+	// .../download.php/file/123/foo.tar.gz
+	// 123 -> file_id
+	// foo.tar.gz ignored
+	$file_id = $expl_pathinfo[4];
+	$File = frsfile_get_object($file_id);
+	if (!$File) {
+		send_404();
+	}
 
+	$Release = $File->FRSRelease;
+	$Package = $Release->FRSPackage;
+	$Group = $Package->Group;
+	if ($Package->isPublic()) {
+		session_require_perm('frs', $Package->Group->getID(), 'read_public');
+	} else {
+		session_require_perm('frs', $Package->Group->getID(), 'read_private');
+	}
 
-//  Members of projects can see all packages
-//  Non-members can only see public packages
-if(!$is_public) {
-	if (!session_loggedin() || !user_ismember($group_id)) {
-		exit_permission_denied();
+	$filename = $File->getName();
+	$filepath = forge_get_config('upload_dir').'/'.$Group->getUnixName().'/'.$Package->getFileName().'/'.$Release->getFileName().'/'.$filename;
+
+	send_file ($filename, $filepath, $file_id);
+
+	break;
+					
+case 'latestzip':
+	// .../download.php/latestzip/123/package-latest.zip
+	// 123 -> package_id
+	// package-latest.zip ignored
+	$package_id = $expl_pathinfo[4];
+
+	$Package = frspackage_get_object($package_id);
+	if (!$Package || !$Package->getNewestRelease()) {
+		send_404();
 	}
-}
-if ($GLOBALS['sys_block_anonymous_downloads']) {
-	if (!session_loggedin()) {
-		exit_permission_denied();
+
+	if ($Package->isPublic()) {
+		session_require_perm('frs', $Package->Group->getID(), 'read_public');
+	} else {
+		session_require_perm('frs', $Package->Group->getID(), 'read_private');
 	}
-}
 
-$filepath=forge_get_config('upload_dir').'/'.$Group->getUnixName().'/'.$Package->getFileName().'/'.$Release->getFileName().'/'.$File->getName();
-if (file_exists($filepath)) {
-	Header('Content-disposition: attachment; filename="'.str_replace('"', '', $filename).'"');
-	Header("Content-type: application/binary");
-	$length = filesize($filepath);
-	Header("Content-length: $length");
+	$filename = $Package->getNewestReleaseZipName();
+	$filepath = $Package->getNewestReleaseZipPath();
+	send_file ($filename, $filepath);
 
-	readfile_chunked($filepath);
+	break;
 
-	if (session_loggedin()) {
-		$s =& session_get_user();
-		$us=$s->getID();
+case 'latestfile':
+	// .../download.php/latestfile/123/foo.tar.gz
+	// 123 -> package_id
+	// foo.tar.gz -> file name
+	$package_id = $expl_pathinfo[4];
+	$file_name = $expl_pathinfo[5];
+
+	$res = db_query_params ('SELECT f.file_id FROM frs_file f, frs_release r, frs_package p WHERE f.release_id = r.release_id AND r.package_id = p.package_id AND p.package_id = $1 AND f.filename = $2 ORDER BY f.release_id DESC',
+				array($package_id, $file_name));
+
+	if (!$res || db_numrows($res) < 1) {
+		send_404();
+	}
+
+	$row = db_fetch_array($res);
+	$file_id = $row['file_id'];
+	$File = frsfile_get_object($file_id);
+		
+	$Release = $File->FRSRelease;
+	$Package = $Release->FRSPackage;
+	$Group = $Package->Group;
+	if ($Package->isPublic()) {
+		session_require_perm('frs', $Package->Group->getID(), 'read_public');
 	} else {
-		$us=100;
+		session_require_perm('frs', $Package->Group->getID(), 'read_private');
 	}
 
-	$ip=getStringFromServer('REMOTE_ADDR');
-	$res=db_query_params("INSERT INTO frs_dlstats_file (ip_address,file_id,month,day,user_id) 
-		VALUES ($1, $2, $3, $4, $5)", array($ip,$file_id,date('Ym'),date('d'),$us));
-} else {
-	header("HTTP/1.0 404 Not Found");
-	require_once $gfwww.'404.php';
+	$filename = $File->getName();
+	$filepath = forge_get_config('upload_dir').'/'.$Group->getUnixName().'/'.$Package->getFileName().'/'.$Release->getFileName().'/'.$filename;
+
+	send_file ($filename, $filepath, $file_id);
+
+	break;
 }
 
+// Local Variables:
+// mode: php
+// c-file-style: "bsd"
+// End:
+
 ?>

Modified: trunk/src/www/frs/index.php
===================================================================
--- trunk/src/www/frs/index.php	2011-01-13 16:06:28 UTC (rev 11981)
+++ trunk/src/www/frs/index.php	2011-01-13 16:10:35 UTC (rev 11982)
@@ -109,12 +109,12 @@
 			$package_monitor = util_make_link ( $url, $GLOBALS['HTML']->getMonitorPic($title));
 		} else {
 			$title = db_result($res_package, $p, 'name') . " - " . _('Monitor this package');
-            $url = '/frs/monitor.php?filemodule_id='. db_result($res_package, $p, 'package_id') .'&group_id='.db_result($res_package,$p,'group_id').'&start=1';
+			$url = '/frs/monitor.php?filemodule_id='. db_result($res_package, $p, 'package_id') .'&group_id='.db_result($res_package,$p,'group_id').'&start=1';
 			$package_monitor = util_make_link ( $url, $GLOBALS['HTML']->getMonitorPic($title));
 		}
 
-        $package_name_protected = $HTML->toSlug($package_name);
-        echo "\n".'<h2 id="title_'. $package_name_protected .'">' . $package_name . ' <span class="frs-monitor-package">' . $package_monitor . '</span></h2>'."\n";
+		$package_name_protected = $HTML->toSlug($package_name);
+		echo "\n".'<h2 id="title_'. $package_name_protected .'">' . $package_name . ' <span class="frs-monitor-package">' . $package_monitor . '</span></h2>'."\n";
 		
 		// get the releases of the package
 		$res_release = db_query_params ('SELECT * FROM frs_release
@@ -129,6 +129,13 @@
 			echo '<div class="warning">' . _('No releases') . '</div>
 			';
 		} else {
+			// display link to latest-release-as-zip
+			print '<p><em>'._('Download latest release as zip:').' ';
+			print util_make_link ('/frs/download.php/latestzip/'.$frsPackage->getID().'/'.$frsPackage->getNewestReleaseZipName(),
+					      $frsPackage->getNewestReleaseZipName(),
+					      array('title' => _('This link always points to the newest release as a zip file.')));
+			print '</em></p>';
+
 			// iterate and show the releases of the package
 			for ( $r = 0; $r < $num_releases; $r++ ) {
                 $package_release = db_fetch_array( $res_release );
@@ -171,6 +178,7 @@
                 $cell_data[] = _('D/L');
                 $cell_data[] = _('Arch');
                 $cell_data[] = _('Type');
+                $cell_data[] = _('Latest');
 
                 // Switch whether release_id exists and/or release_id == package_release['release_id']
                 if ( ! $release_id ) {
@@ -186,19 +194,20 @@
                 if ( ! $release_id || $release_id==$package_release['release_id'] ) {
                     // no release_id OR no release_id OR release_id is current one
                     if ( !$res_file || $num_files < 1 ) {
-                        echo '<tr><td colspan="6">  <em>'._('No releases').'</em></td></tr>
+                        echo '<tr><td colspan="7">  <em>'._('No releases').'</em></td></tr>
                         ';
                     } else {
                         // now iterate and show the files in this release....
                         for ( $f = 0; $f < $num_files; $f++ ) {
                             $file_release = db_fetch_array( $res_file );
 
-                            $tmp_col1 = util_make_link ('/frs/download.php/'.$file_release['file_id'].'/'.$file_release['filename'], $file_release['filename']);
+                            $tmp_col1 = util_make_link ('/frs/download.php/file/'.$file_release['file_id'].'/'.$file_release['filename'], $file_release['filename']);
                             $tmp_col2 = date(_('Y-m-d H:i'), $package_release['release_date'] );
                             $tmp_col3 = human_readable_bytes($file_release['file_size']);
                             $tmp_col4 = ($file_release['downloads'] ? number_format($file_release['downloads'], 0) : '0');
                             $tmp_col5 = $file_release['processor'];
                             $tmp_col6 = $file_release['type'];
+                            $tmp_col7 = util_make_link ('/frs/download.php/latestfile/'.$frsPackage->getID().'/'.$file_release['filename'], _('Latest version'));
 
                             $proj_stats['size'] += $file_release['file_size'];
                             @$proj_stats['downloads'] += $file_release['downloads'];
@@ -210,6 +219,7 @@
                             echo ' <td>' . $tmp_col4 . '</td>'."\n";
                             echo ' <td>' . $tmp_col5 . '</td>'."\n";
                             echo ' <td>' . $tmp_col6 . '</td>'."\n";
+                            echo ' <td>' . $tmp_col7 . '</td>'."\n";
                             echo '</tr>'."\n";
                         }
                     }
@@ -225,22 +235,6 @@
 			} //for: release(s)
 		} //if: release(s) available
 	}
-// print statistics for this table datas
-/*
-	if ( $proj_stats['size'] ) {
-		print '<tr><td colspan="8"> </tr>'."\n";
-		print '<tr><td><strong>'._('Project totals').'</strong></td>'
-		. '<td align="right"><strong><em>' . $proj_stats['releases'] . '</em></strong></td>'
-		. '<td align="right"><strong><em>' . $proj_stats['files'] . '</em></strong></td>'
-		. '<td align="right"><strong><em>' . human_readable_bytes($proj_stats['size']) . '</em></strong></td>'
-		. '<td align="right"><strong><em>' . $proj_stats['downloads'] . '</em></strong></td>'
-		. '<td colspan="3"> </td></tr>'."\n";
-	}
-
-	print "</table>\n\n";
-}
-*/
-
 echo '</div><!-- id="forge-frs" -->';
 
 }




More information about the Fusionforge-commits mailing list