Explorar o código

Extras module now uses github repositories.
It takes some time to load the first time.

DieFeM %!s(int64=9) %!d(string=hai) anos
pai
achega
1f2b85ec55

+ 244 - 135
modules/extras/extras.php

@@ -40,20 +40,9 @@ function rmdir_recurse($path) {
 
 function getMyFile($url,$destination)
 {
-	$ch = curl_init();
-	curl_setopt($ch, CURLOPT_URL, $url);
-	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
-	curl_setopt($ch, CURLOPT_HEADER, false); 
-	curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
-	curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
-	curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
-	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
-	$date = new DateTime();
-	$expires = gmdate('D, d-M-Y H:i:s \G\M\T', $date->getTimestamp() + 31536000000);
-	curl_setopt($ch, CURLOPT_COOKIE, "FreedomCookie=true;path=/;expires=".$expires);
-	//Save Page
-	$result = curl_exec($ch);
-	curl_close($ch);
+	$result = file_get_contents($url);
+	if(!$result)
+		return $result;
 	return file_put_contents($destination, $result);
 }
 
@@ -67,17 +56,9 @@ function installUpdate($info, $base_dir)
 		echo get_lang_f('unable_download',$info['title'])."\n";
 		return;
 	}
-	
-	$calcMD5 = md5_file( $temp_dwl );
-	if($calcMD5 != $info['md5'])
-	{
-		echo get_lang_f('md5_failed',$info['title']);
-		unlink($temp_dwl);
-		return;
-	}
-	
+		
 	// Set default values for file checkings before installing
-	$not_writable = get_lang( 'can_not_update_non_writable_files' )." :\n";
+	$not_writable = can_not_update_non_writable_files ." :\n";
 	$filename = "";
 	$overwritten = 0;
 	$new = 0;
@@ -90,11 +71,11 @@ function installUpdate($info, $base_dir)
 	if( !file_exists($temp_dir) )
 		mkdir($temp_dir, 0775);
 	
-	$result = extractZip( $temp_dwl, $temp_dir . DIRECTORY_SEPARATOR );
+	$result = extractZip( $temp_dwl, $temp_dir . DIRECTORY_SEPARATOR, $info['remove_path'] );
 		
 	if ( is_array($result['extracted_files']) and count($result['extracted_files']) > 0 )
 	{
-		$nfo_file = preg_replace("/themes\/themes/","themes",$base_dir.$info['install_path']."/install.nfo");
+		$nfo_file = DATA_PATH . str_replace(' ','_',$info['title']) . ".nfo";
 		$install_nfo = $info['timestamp']."\n$nfo_file\n";
 		// Check file by file if already exists, if it matches, compares both files 
 		// looking for changes determining if the file needs to be updated.
@@ -103,8 +84,13 @@ function installUpdate($info, $base_dir)
 		$i = 0;
 		foreach( $result['extracted_files'] as $file )
 		{
-			$install_nfo .= $base_dir.$file['filename']."\n";
-			$filename = $file['filename'];
+			if( DIRECTORY_SEPARATOR == '\\')
+				$filename = str_replace('/', '\\', $file['filename']);
+			else
+				$filename = $file['filename'];
+			
+			$filename = preg_replace( "/".preg_quote($info['remove_path'])."/", "", $filename);
+			$install_nfo .= realpath($base_dir) . $filename . "\n";
 			$temp_file = $temp_dir . DIRECTORY_SEPARATOR . $filename;
 			$web_file = $base_dir . $filename;
 			
@@ -166,7 +152,7 @@ function installUpdate($info, $base_dir)
 	if( $all_writable )
 	{
 		// Extract the files that are set in $filelist, to the folder at $base_dir.
-		$result = extractZip( $temp_dwl, $base_dir, '', '', $filelist );
+		$result = extractZip( $temp_dwl, $base_dir, $info['remove_path'], '', $filelist );
 		
 		if( is_array( $result['extracted_files'] ) )
 		{
@@ -182,7 +168,7 @@ function installUpdate($info, $base_dir)
 			}
 						
 			// Add install.nfo file to the module/theme directory so we can remove the installed files later and check the installed files timestamp.
-			file_put_contents($info['install_path']."/install.nfo", $install_nfo);
+			file_put_contents($nfo_file, $install_nfo);
 			// Remove the downloaded package
 			if( file_exists( $temp_dwl ) )
 				unlink( $temp_dwl );
@@ -190,7 +176,6 @@ function installUpdate($info, $base_dir)
 		}
 		else
 		{
-			echo $result;
 			// Remove the downloaded package
 			if( file_exists( $temp_dwl ) )
 				unlink( $temp_dwl );
@@ -206,82 +191,202 @@ function installUpdate($info, $base_dir)
 		return FALSE;
 	}
 }
+
+function rglob($pattern, $flags = 0) {
+    $files = glob($pattern, $flags); 
+    foreach (glob(dirname($pattern).'/*', GLOB_ONLYDIR|GLOB_NOSORT) as $dir) {
+        $files = array_merge($files, rglob($dir.'/'.basename($pattern), $flags));
+    }
+    return $files;
+}
+
+function deeperPathFirst($a, $b)
+{
+	$al = count(explode(DIRECTORY_SEPARATOR,$a));
+	$bl = count(explode(DIRECTORY_SEPARATOR,$b));
+	if ($al == $bl) {
+		return strcmp($a,$b);
+	}
+	return ($al > $bl) ? -1 : +1;
+}
  
 function exec_ogp_module() 
 {
 	set_time_limit(0);
+	$baseDir = str_replace( "modules" . DIRECTORY_SEPARATOR . $_GET['m'],"",dirname(__FILE__) );
+	define('DATA_PATH', realpath('modules/'.$_GET['m'].'/') . DIRECTORY_SEPARATOR . "data" . DIRECTORY_SEPARATOR);
+	
+	if(!file_exists(DATA_PATH))
+	{
+		if(!mkdir(DATA_PATH))
+		{
+			print_failure("Need create folder: " . DATA_PATH . ' <br>But ' . dirname(DATA_PATH) . ' is not writable.<br>The command: <pre>chmod -R ' . dirname(DATA_PATH) . '</pre> would fix it.');
+			return;
+		}
+		
+		$back_compatibility = [ 'Util',
+								'RCON',
+								'DSi',
+								'Cron',
+								'LGSL_with_Img_Mod',
+								'Simple-billing',
+								'Support',
+								'TeamSpeak3',
+								'DarkNature',
+								'expand-soft',
+								'Katiuska',
+								'mobile',
+								'Light',
+								'Silver',
+								'Soft',
+								'Uprise' ];
+		
+		$installed = rglob('*/*/install.nfo');
+		
+		foreach($installed as $nfo)
+		{
+			$nfo_new = preg_replace('#^([m|t]{1})(odule|heme){1}s/([^?/]+)/install.nfo#','\3',$nfo);
+			#echo $nfo_new.'<br>';
+			$matches = preg_grep('#'.preg_quote($nfo_new).'#i',$back_compatibility);	
+			sort($matches);
+			if($nfo_new == 'fastdl')
+				$matches[0] = 'Fast_Download';
+			if(isset($matches[0]))
+			{
+				#echo DATA_PATH.$matches[0].'.nfo<br>';
+				file_put_contents(DATA_PATH.$matches[0].'.nfo', file_get_contents($nfo));
+			}
+			unlink($nfo);
+		}
+	}
+	#return;
+	define('REPO_FILE', DATA_PATH . "repos");
+	define('URL', 'https://api.github.com/orgs/OpenGamePanel/repos'); // Returns detailed information of all repositories, and urls for more detailed informations about. Nice API GitHub! :)
+	if(!file_exists(REPO_FILE) or isset($_GET['searchForUpdates']) or isset($_POST['update']))
+	{
+		# Without this $context the file_get_contents function was returning HTTP/1.0 403 Forbidden
+		# Thanks: https://github.com/philsturgeon/codeigniter-oauth2/issues/57#issuecomment-29306192 
+		$options  = array('http' => array('user_agent'=> $_SERVER['HTTP_USER_AGENT']));
+		$context  = stream_context_create($options);
+		$response = file_get_contents(URL, false, $context);
+		file_put_contents(REPO_FILE,$response);
+	}
+	else
+	{
+		$response = file_get_contents(REPO_FILE);
+	}
+
+	# Converting json string to array
+	# http://php.net/manual/es/function.json-decode.php mixed json_decode ( string $json [, bool $assoc = false [, int $depth = 512 [, int $options = 0 ]]] ) 
+	# *options - Bitmask of JSON decode options. Currently only JSON_BIGINT_AS_STRING is supported (default is to cast large integers as floats)
+	$repos_info_array = json_decode($response, true);
+	# Checking for contents while debbuging
+	/* echo "<xmp>";
+	print_r($repos_info_array);
+	echo "</xmp>"; */
+
 	if(isset($_POST['remove']))
 	{
-		$themeDirRelPath = $_POST['remove'] . "/" . $_POST['folder'];
-		if(file_exists($themeDirRelPath) && is_dir($themeDirRelPath)){
-			recursiveDelete($themeDirRelPath);
+		$install_nfo = DATA_PATH . str_replace(' ','_',$_POST['folder']) . ".nfo";
+		if( file_exists($install_nfo) )
+		{
+			$lines = file($install_nfo);
+			unset($lines[0]);// timestamp
+			unset($lines[1]);// nfo file
+			usort($lines, "deeperPathFirst");
+			foreach($lines as $file)
+			{
+				$file = trim($file);
+				if(file_exists($file))
+				{
+					unlink($file);
+					$parent_directory = dirname($file);
+					while(count(scandir($parent_directory)) == 2)
+					{							
+						if(realpath($parent_directory) == realpath($baseDir))
+							break;						
+						if(is_writable($parent_directory))
+							rmdir($parent_directory);
+						else
+							break;
+						$parent_directory = dirname($parent_directory);
+					}
+				}
+			}
+			unlink($install_nfo);
 		}
 		return;
 	}
-	$url = 'http://sourceforge.net/projects/ogpextras/rss?limit=200'; // Increased limit from 50 to 200 since SourceForge lists 51 entries in the RSS for alternative snapshots.
-	require_once 'rss_php.php';
-	$rss = new rss_php;
-	$rss->load($url);
-	$items = $rss->getItems(); #returns all rss items
-
+	
 	$m = 0;
 	$modules = array();
 	$t = 0;
 	$themes = array();
-
-	foreach ($items as $index => $item)
+	foreach($repos_info_array as $key => $repository)
 	{
-		if(preg_match("/(Mods|Alternative-Snapshot)/",$item['title']))continue;
+		if(preg_match('/^(OGP-Website|OGP-Agent-Linux|OGP-Agent-Windows)$/',$repository['name']))
+			continue;
 		
-		if(preg_match("/\/Modules\//",$item['title']))
+		$REMOTE_REPO_FILE = 'https://github.com/OpenGamePanel/'.$repository['name'].'/commits/master.atom';
+		$LOCAL_REPO_FILE = DATA_PATH . $repository['name'] . '.atom';
+		if(!file_exists($LOCAL_REPO_FILE) OR (isset($_GET['searchForUpdates']) and $_GET['searchForUpdates'] == $repository['name']) OR isset($_POST['update']))
 		{
-			$pubDate = explode(",",$item['pubDate']);
-			$pubDate = $pubDate[1];
-			$pubDate = explode(" ",$pubDate);
-			array_pop($pubDate);
-			$pubDate = implode(" ",$pubDate);
-			$item['pubDate'] = $pubDate;
-			$module_title = preg_replace("/(\/Modules\/|\.zip)/","",$item['title']);
-			$modules[$m]['title'] = $module_title;
-			$modules[$m]['file'] = str_replace("/Modules/","",$item['title']);
-			$modules[$m]['link'] = (string)$item['link'];
-			$modules[$m]['date'] = $item['pubDate'];
-			$modules[$m]['timestamp'] = strtotime($item['pubDate']);
-			$modules[$m]['md5'] = $item['media:content']['media:hash'];
-			$module_fld = strtolower($module_title);
-			$module_fld = $module_fld == 'simple-billing' ? 'billing' : $module_fld;
-			$module_fld = $module_fld == 'lgsl + img mod' ? 'lgsl' : $module_fld;
-			$module_fld = $module_fld == 'fast download' ? 'fastdl' : $module_fld;
-			$modules[$m]['install_path'] = MODULES.$module_fld;
-			$m++;
+			$used_file = $REMOTE_REPO_FILE;
+			$contents = file_get_contents($used_file);
+			if(file_put_contents($LOCAL_REPO_FILE, $contents))
+				touch($LOCAL_REPO_FILE);
 		}
-		if(preg_match("/\/Themes\//",$item['title']))
+		else
+		{
+			$used_file = $LOCAL_REPO_FILE;
+			$contents = file_get_contents($used_file);
+		}
+		
+		if( ! $contents )
 		{
-			$pubDate = explode(",",$item['pubDate']);
-			$pubDate = $pubDate[1];
-			$pubDate = explode(" ",$pubDate);
-			array_pop($pubDate);
-			$pubDate = implode(" ",$pubDate);
-			$item['pubDate'] = $pubDate;
-			$theme_title = preg_replace("/(\/Themes\/|\.zip)/","",$item['title']);
-			$themes[$t]['title'] = $theme_title;
-			$themes[$t]['file'] = str_replace("/Themes/","",$item['title']);
-			$themes[$t]['link'] = (string)$item['link'];
-			$themes[$t]['date'] = $item['pubDate'];
-			$themes[$t]['timestamp'] = strtotime($item['pubDate']);
-			$themes[$t]['md5'] = $item['media:content']['media:hash'];
-			$themes[$t]['install_path'] = 'themes/'.$theme_title;
-			$t++;
+			print_failure('Unable to get contents from : ' . $used_file);
+			continue;
+		}
+		$feedXml = new SimpleXMLElement($contents, LIBXML_NOCDATA);
+		$seed = basename(  (string) $feedXml->entry[0]->link['href'] );
+		/* echo "<xmp>";
+		print_r($feedXml);
+		echo "</xmp>"; */
+		if($seed)
+		{
+			if(preg_match("/^Module-/",$repository['name']))
+			{
+				$module_title = preg_replace(array("/^Module-/i","/_/"),array(""," "),$repository['name']);
+				$modules[$m]['title'] = $module_title;
+				$modules[$m]['reponame'] = $repository['name'];
+				$modules[$m]['file'] = $seed.'.zip';
+				$modules[$m]['link'] = 'https://github.com/OpenGamePanel/'.$repository['name'].'/archive/'.$seed.'.zip';
+				$modules[$m]['date'] = (string) $feedXml->entry[0]->updated;
+				$modules[$m]['timestamp'] = strtotime((string) $feedXml->entry[0]->updated);
+				$modules[$m]['remove_path'] = $repository['name']."-".$seed;
+				$m++;
+			}
+			if(preg_match("/^Theme-/",$repository['name']))
+			{
+				$theme_title = preg_replace("/Theme-/i","",$repository['name']);
+				$themes[$t]['title'] = $theme_title;
+				$themes[$t]['reponame'] = $repository['name'];
+				$themes[$t]['file'] = $seed.'.zip';
+				$themes[$t]['link'] = 'https://github.com/OpenGamePanel/'.$repository['name'].'/archive/'.$seed.'.zip';
+				$themes[$t]['date'] = (string) $feedXml->entry[0]->updated;
+				$themes[$t]['timestamp'] = strtotime((string) $feedXml->entry[0]->updated);
+				$themes[$t]['remove_path'] = $repository['name']."-".$seed;
+				$t++;
+			}
 		}
 	}
-
+		
 	global $db;
 	$installed_modules = $db->getInstalledModules();
 	
 	if(isset($_POST['update']))
 	{
-		$baseDir = str_replace( "modules" . DIRECTORY_SEPARATOR . "extras","",dirname(__FILE__) );
-		$temesFolder = $baseDir . "themes" . DIRECTORY_SEPARATOR;
+		$baseDir = str_replace( "modules" . DIRECTORY_SEPARATOR . $_GET['m'],"",dirname(__FILE__) );
 		$uMF = array();
 		$tmpdir = get_temp_dir(dirname(__FILE__));
 		if( !is_writable( $tmpdir ) )
@@ -289,13 +394,6 @@ function exec_ogp_module()
 			echo get_lang_f('temp_folder_not_writable', $tmpdir);
 			return;
 		}
-		$use_custom_mirror = false;
-		if(isset($_POST['mirror']))
-		{
-			$mirror = $_POST['mirror'];
-			unset($_POST['mirror']);
-			$use_custom_mirror = true;
-		}
 		foreach($_POST as $key => $value)
 		{
 			if($key == 'update')continue;
@@ -304,22 +402,22 @@ function exec_ogp_module()
 			{
 				foreach($value as $m)
 				{
-					$info = $modules[$m];
-					if($use_custom_mirror)
-						$info['link'] = preg_replace("/(.*)\/\/(.*)projects(.*)\/files(.*)\/download/","$1//$mirror.dl.$2project$3$4",$info['link']);
-					if(installUpdate($info, $baseDir))
-						$uMF[] = str_replace(MODULES,"",$info['install_path']);
-				}
+					if(installUpdate($modules[$m], $baseDir))
+					{
+						$install_nfo = DATA_PATH . str_replace(' ','_',$modules[$m]['title']) . ".nfo";
+						$nfo = file_get_contents($install_nfo);
+						$modules_dir_preg = preg_quote(realpath('modules') . DIRECTORY_SEPARATOR);
+						$modulephp_preg = preg_quote(DIRECTORY_SEPARATOR . 'module.php');
+						$preg = '#'.$modules_dir_preg.'(.*)'.$modulephp_preg.'#';
+						if(preg_match($preg, $nfo, $matches))
+							$uMF[] = $matches[1];
+					}
+				}	
 			}
 			if($key == 'theme')
 			{
 				foreach($value as $t)
-				{
-					$info = $themes[$t];
-					if($use_custom_mirror)
-						$info['link'] = preg_replace("/(.*)\/\/(.*)projects(.*)\/files(.*)\/download/","$1//$mirror.dl.$2project$3$4",$info['link']);
-					installUpdate($info, $temesFolder);
-				}
+					installUpdate($themes[$t], $baseDir);
 			}
 		}
 		
@@ -337,20 +435,14 @@ function exec_ogp_module()
 		return;
 	}
 	
-	echo "<h2>".get_lang('extras')."</h2>";
+	echo "<h2>".extras."</h2>";
+		
 	echo "<table style=\"width:100%;\">";
 
-	if ( ini_get('open_basedir') or get_true_boolean(ini_get('safe_mode')) )
-	{
-		echo "<tr><td colspan=2 style='text-align:center;' >";
-		$sf_mirrors = file("modules/extras/mirrors.list");
-		echo get_lang('select_mirror').": ".create_drop_box_from_array_rsync($sf_mirrors,"mirror");
-		echo "</td></tr>";
-	}
 	echo "<tr><td style=\"width:50%;\">";
 	# MODULES
 	echo "<div class=\"dragbox bloc rounded\" style=\"margin:1%;\">".
-		 "<h4>".get_lang('extra_modules')."</h4>".
+		 "<h4>".extra_modules."</h4>".
 		 "<div class=\"dragbox-content\" >";
 	
 	foreach ( $installed_modules as $installed_module )
@@ -361,23 +453,32 @@ function exec_ogp_module()
 	
 	foreach($modules as $key => $module)
 	{
-		$on_disk = file_exists($module['install_path']."/module.php");
-		$folder = str_replace(MODULES,"",$module['install_path']);
+		$local_repo_file = DATA_PATH . $module['reponame'] . '.atom';
+		$install_nfo = DATA_PATH . str_replace(' ','_',$module['title']) . ".nfo";
+		$on_disk = file_exists($install_nfo);
+		$is_old = $on_disk && (strtotime('+1 hour', filemtime($local_repo_file)) <= time());
+		//echo $install_nfo;
+		$folder = str_replace(' ','_',strtolower($module['title']));
 		$installed = array_key_exists($folder,$installed_modules_by_folder);
 		
 		$installed_str = $on_disk ? $installed ? "<a class='uninstall' style='color:blue;' data-module-folder='$folder' data-module-id='".
-												 $installed_modules_by_folder[$folder]."' href='#uninstall_$folder' >".get_lang('uninstall')."</a>" : 
-												 "<a class='install' style='color:blue;' data-module-folder='$folder' href='#install_$folder' >".get_lang('install')."</a> - ".
-												 "<a class='remove' style='color:red;' data-module-folder='$folder' data-remove-mode='modules' href='#remove_$folder' >".get_lang('remove')."</a>" : 
-												 "<b style='color:red;' >".get_lang('not_installed')."</b>";
+												 $installed_modules_by_folder[$folder]."' href='#uninstall_$folder' >".uninstall."</a>" : 
+												 "<a class='install' style='color:blue;' data-module-folder='$folder' href='#install_$folder' >".install."</a> - ".
+												 "<a class='remove' style='color:red;' data-module-folder='$module[title]' data-remove-mode='modules' href='#remove_$folder' >".remove."</a>" : 
+												 "<b style='color:red;' >".not_installed."</b>";
 		$uptodate = FALSE;
-		if(file_exists($module['install_path']."/install.nfo"))
+		if($on_disk)
 		{
-			$install_nfo = file_get_contents($module['install_path']."/install.nfo");
+			$install_nfo = file_get_contents($install_nfo);
 			list($timestamp, $files) = explode("\n", $install_nfo);
 			$uptodate = ($timestamp == $module['timestamp']) ? TRUE : FALSE;
 		}
-		$updated_str = $on_disk ? $uptodate ? " - <b style='color:green;' >".get_lang('uptodate')."</b>" : " - <b style='color:orange;' >".get_lang('update_available')."</b> (".$module['date'].")" : "";
+		$updated_str =	$on_disk ?
+							$uptodate ? 
+								$is_old ? " - <a class='search' style='color:brown;' href='?m=".$_GET['m']."&searchForUpdates=".$module['reponame']."' >".search_for_updates."</a>" : 
+								" - <b style='color:green;' >".uptodate."</b>" : 
+							" - <b style='color:orange;' >".update_available."</b> (".$module['date'].")" : 
+						"";
 		$disabled = $uptodate ? "disabled=disabled" : "";
 		echo '<input type="checkbox" name="module" value="'.$key."\" $disabled>";
 		echo '<b>'.$module['title']."</b> - $installed_str$updated_str <span id='loading' class='$folder' ></span><br>";
@@ -387,38 +488,46 @@ function exec_ogp_module()
 	
 	# THEMES
 	echo "<div class=\"dragbox bloc rounded\" style=\"margin:1%;\">".
-		 "<h4>".get_lang('extra_themes')."</h4>".
+		 "<h4>".extra_themes."</h4>".
 		 "<div class=\"dragbox-content\" >";
-	
 	foreach($themes as $key => $theme)
 	{
-		$installed = file_exists($theme['install_path']);
-		$folder = str_replace("themes/","",$theme['install_path']);
-		$installed_str = $installed ? "<b style='color:green;' >".get_lang('installed')."</b> - ".
-									  "<a class='remove' style='color:red;' data-module-folder='$folder' data-remove-mode='themes' href='#remove_$folder' >".get_lang('remove')."</a>": 
-									  "<b style='color:red;' >".get_lang('not_installed')."</b>";
+		$local_repo_file = DATA_PATH . $theme['reponame'] . '.atom';
+		$install_nfo = DATA_PATH . str_replace(' ','_',$theme['title']) . ".nfo";
+		$on_disk = file_exists($install_nfo);
+		$is_old = $on_disk && (strtotime('+1 hour', filemtime($local_repo_file)) <= time());
+		$installed_str = $on_disk ? "<b style='color:green;' >".installed."</b> - ".
+									"<a class='remove' style='color:red;' data-module-folder='$theme[title]' data-remove-mode='themes' href='#remove_$folder' >".remove."</a>": 
+									"<b style='color:red;' >".not_installed."</b>";
 		$uptodate = FALSE;
-		if(file_exists($theme['install_path']."/install.nfo"))
+		if($on_disk)
 		{
-			$install_nfo = file_get_contents($theme['install_path']."/install.nfo");
+			$install_nfo = file_get_contents($install_nfo);
 			list($timestamp, $files) = explode("\n", $install_nfo);
 			$uptodate = ($timestamp == $theme['timestamp']) ? TRUE : FALSE;
 		}
-		$updated_str = $installed ? $uptodate ? " - <b style='color:green;' >".get_lang('uptodate')."</b>" : " - <b style='color:orange;' >".get_lang('update_available')."</b> (".$theme['date'].")" : "";
+		
+		
+		$updated_str =	$on_disk ? 
+							$uptodate ? 
+								$is_old ? " - <a class='search' style='color:brown;' href='?m=".$_GET['m']."&searchForUpdates=".$theme['reponame']."' >".search_for_updates."</a>" : 
+								" - <b style='color:green;' >".uptodate."</b>" :
+							" - <b style='color:orange;' >".update_available."</b> (".$theme['date'].")" :
+						"";
 		$disabled = $uptodate ? "disabled=disabled" : "";
 		echo '<input type="checkbox" name="theme" value="'.$key."\" $disabled>";
 		echo '<b>'.$theme['title']."</b> - $installed_str$updated_str<br>";
 	}
 	
 	echo "</div></div></td></tr>".
-		 "<tr><td colspan=2 ><span id=updateButton ><button name=update >".get_lang('download_update')."</button></span></td></tr></table><div id=resp ></div>";
+		 "<tr><td colspan=2 ><span id=updateButton ><button name=update >".download_update."</button></span></td></tr></table><div id=resp ></div>";
 	
 	echo "<div id='dialog".
-		 "' data-uninstalling_module_dataloss='".get_lang('uninstalling_module_dataloss').
-		 "' data-are_you_sure='".get_lang('are_you_sure').
-		 "' data-remove_files_for='".get_lang('remove_files_for').
-		 "' data-confirm='".get_lang('confirm').
-		 "' data-cancel='".get_lang('cancel').
+		 "' data-uninstalling_module_dataloss='".uninstalling_module_dataloss.
+		 "' data-are_you_sure='".are_you_sure.
+		 "' data-remove_files_for='".remove_files_for.
+		 "' data-confirm='".confirm.
+		 "' data-cancel='".cancel.
 		 "' ></div>";
 }
 ?>

+ 0 - 17
modules/extras/mirrors.list

@@ -1,17 +0,0 @@
-master|SourceForge, Inc. (Chicago, Illinois, US)
-aarnet|AARNet (Melbourne, Australia, AU)
-citylan|CityLan (Moscow, Russian Federation, RU)
-freefr|Free France (Paris, France, FR)
-garr|garr.it (Ancona, Italy, IT)
-heanet|HEAnet (Ireland, IE)
-hivelocity|HiVelocity (Tampa, FL, US)
-internode|Internode (Adelaide, Australia, AU)
-jaist|Japan Advanced Institute of Science and Technology (Nomi, Japan, JP)
-kaz|kaz.kz (Almaty, Kazakhstan, KZ)
-kent|University of Kent (Canterbury, United Kingdom, GB)
-netcologne|NetCologne (K&ouml;ln, Germany, DE)
-optimate|Optimate-Server (Germany, DE)
-softlayer-dal|Softlayer (Dallas, TX, US)
-surfnet|SURFnet (Zurich, Switzerland, CH)
-switch|SWITCH (Zurich, Switzerland, CH)
-ufpr|Centro de Computacao Cientifica e Software Livre (Curitiba, Brazil, BR)

+ 0 - 172
modules/extras/rss_php.php

@@ -1,172 +0,0 @@
-<?php
-/*
-	RSS_PHP - the PHP DOM based RSS Parser
-	Author: <rssphp.net>
-	Published: 200801 :: blacknet :: via rssphp.net
-	
-	RSS_PHP is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY.
-
-	Usage:
-		See the documentation at http://rssphp.net/documentation
-	Examples:
-		Can be found online at http://rssphp.net/examples
-*/
-
-class rss_php {
-	
-	public $document;
-	public $channel;
-	public $items;
-
-/****************************
-	public load methods
-***/
-	# load RSS by URL
-		public function load($url=false, $unblock=true) {
-			if($url) {
-				$ch = curl_init();
-				curl_setopt($ch, CURLOPT_URL, $url);
-				curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)');
-				curl_setopt($ch, CURLOPT_HTTPHEADER,array("Accept-Language: es-es,en"));
-				curl_setopt($ch, CURLOPT_TIMEOUT, 60);
-				curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
-				curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
-				curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
-				curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
-				
-				$date = new DateTime();
-				$expires = gmdate('D, d-M-Y H:i:s \G\M\T', $date->getTimestamp() + 31536000000);
-				curl_setopt($ch, CURLOPT_COOKIE, "FreedomCookie=true;path=/;expires=".$expires);
-				//Save Page
-				$result = curl_exec($ch);
-				curl_close($ch);
-				$this->loadParser($result);
-			}
-		}
-	# load raw RSS data
-		public function loadRSS($rawxml=false) {
-			if($rawxml) {
-				$this->loadParser($rawxml);
-			}
-		}
-		
-/****************************
-	public load methods
-		@param $includeAttributes BOOLEAN
-		return array;
-***/
-	# return full rss array
-		public function getRSS($includeAttributes=false) {
-			if($includeAttributes) {
-				return $this->document;
-			}
-			return $this->valueReturner();
-		}
-	# return channel data
-		public function getChannel($includeAttributes=false) {
-			if($includeAttributes) {
-				return $this->channel;
-			}
-			return $this->valueReturner($this->channel);
-		}
-	# return rss items
-		public function getItems($includeAttributes=false) {
-			if($includeAttributes) {
-				return $this->items;
-			}
-			return $this->valueReturner($this->items);
-		}
-
-/****************************
-	internal methods
-***/
-	private function loadParser($rss=false) {
-		if($rss) {
-			$this->document = array();
-			$this->channel = array();
-			$this->items = array();
-			$DOMDocument = new DOMDocument;
-			$DOMDocument->strictErrorChecking = false;
-			$DOMDocument->loadXML($rss);
-			$this->document = $this->extractDOM($DOMDocument->childNodes);
-		}
-	}
-	
-	private function valueReturner($valueBlock=false) {
-		if(!$valueBlock) {
-			$valueBlock = $this->document;
-		}
-		foreach($valueBlock as $valueName => $values) {
-				if(isset($values['value'])) {
-					$values = $values['value'];
-				}
-				if(is_array($values)) {
-					$valueBlock[$valueName] = $this->valueReturner($values);
-				} else {
-					$valueBlock[$valueName] = $values;
-				}
-		}
-		return $valueBlock;
-	}
-	
-	private function extractDOM($nodeList,$parentNodeName=false) {
-		$itemCounter = 0;
-		foreach($nodeList as $values) {
-			if(substr($values->nodeName,0,1) != '#') {
-				if($values->nodeName == 'item') {
-					$nodeName = $values->nodeName.':'.$itemCounter;
-					$itemCounter++;
-				} else {
-					$nodeName = $values->nodeName;
-				}
-				$tempNode[$nodeName] = array();				
-				if($values->attributes) {
-					for($i=0;$values->attributes->item($i);$i++) {
-						$tempNode[$nodeName]['properties'][$values->attributes->item($i)->nodeName] = $values->attributes->item($i)->nodeValue;
-					}
-				}
-				if(!$values->firstChild) {
-					$tempNode[$nodeName]['value'] = $values->textContent;
-				} else {
-					$tempNode[$nodeName]['value']  = $this->extractDOM($values->childNodes, $values->nodeName);
-				}
-				if(in_array($parentNodeName, array('channel','rdf:RDF'))) {
-					if($values->nodeName == 'item') {
-						$this->items[] = $tempNode[$nodeName]['value'];
-					} elseif(!in_array($values->nodeName, array('rss','channel'))) {
-						$this->channel[$values->nodeName] = $tempNode[$nodeName];
-					}
-				}
-			} elseif(substr($values->nodeName,1) == 'text') {
-				$tempValue = trim(preg_replace('/\s\s+/',' ',str_replace("\n",' ', $values->textContent)));
-				if($tempValue) {
-					$tempNode = $tempValue;
-				}
-			} elseif(substr($values->nodeName,1) == 'cdata-section'){
-				$tempNode = $values->textContent;
-			}
-		}
-		return $tempNode;
-	}
-	
-	private function randomContext() {
-		$headerstrings = array();
-		$headerstrings['User-Agent'] = 'Mozilla/5.0 (Windows; U; Windows NT 5.'.rand(0,2).'; en-US; rv:1.'.rand(2,9).'.'.rand(0,4).'.'.rand(1,9).') Gecko/2007'.rand(10,12).rand(10,30).' Firefox/2.0.'.rand(0,1).'.'.rand(1,9);
-		$headerstrings['Accept-Charset'] = rand(0,1) ? 'en-gb,en;q=0.'.rand(3,8) : 'en-us,en;q=0.'.rand(3,8);
-		$headerstrings['Accept-Language'] = 'en-us,en;q=0.'.rand(4,6);
-		$setHeaders = 	'Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5'."\r\n".
-						'Accept-Charset: '.$headerstrings['Accept-Charset']."\r\n".
-						'Accept-Language: '.$headerstrings['Accept-Language']."\r\n".
-						'User-Agent: '.$headerstrings['User-Agent']."\r\n";
-		$contextOptions = array(
-			'http'=>array(
-				'method'=>"GET",
-				'header'=>$setHeaders
-			)
-		);
-		return stream_context_create($contextOptions);
-	}
-	
-}
-
-?>

+ 207 - 0
modules/update/blacklist.css

@@ -0,0 +1,207 @@
+span.chattrLock{
+	padding-left: 20px;
+	background: url(../../images/locked.png) no-repeat left center;
+	color: black; 
+	font-size: 12px; 
+	height: 16px;
+}
+
+span.chattrUnlock{
+	padding-left: 20px;
+	background: url(../../images/unlocked.png) no-repeat left center;
+	color: black; 
+	font-size: 12px; 
+	height: 16px;
+}
+
+div.chattrButton{
+	color: white;
+	font-size: 12px; 
+	height: 16px;
+	text-align: center;
+	vertical-align: middle;
+	padding-right: 16px;
+	cursor:pointer;
+	-webkit-border-radius: 9px;
+	-moz-border-radius: 9px;
+	border-radius: 9px;
+	padding-bottom:2px;
+	width: 150px;
+}
+
+/* UNLOCKED */
+div.chattrButton.unlocked i{
+	background: url(../../images/unlocked.png) no-repeat left center;
+	height:16px;
+	width:16px;
+	display: inline-block;
+	float:left;
+}
+
+div.chattrButton.unlocked{
+	border-bottom:2px solid #1e5799;
+	border-right:2px solid #1e5799;
+	border-top:2px solid #7db9e8;
+	border-left:2px solid #7db9e8;
+	background: #7db9e8; /* Old browsers */
+	background: -moz-linear-gradient(top,  #7db9e8 0%, #207cca 49%, #2989d8 50%, #1e5799 100%); /* FF3.6+ */
+	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#7db9e8), color-stop(49%,#207cca), color-stop(50%,#2989d8), color-stop(100%,#1e5799)); /* Chrome,Safari4+ */
+	background: -webkit-linear-gradient(top,  #7db9e8 0%,#207cca 49%,#2989d8 50%,#1e5799 100%); /* Chrome10+,Safari5.1+ */
+	background: -o-linear-gradient(top,  #7db9e8 0%,#207cca 49%,#2989d8 50%,#1e5799 100%); /* Opera 11.10+ */
+	background: -ms-linear-gradient(top,  #7db9e8 0%,#207cca 49%,#2989d8 50%,#1e5799 100%); /* IE10+ */
+	background: linear-gradient(to bottom,  #7db9e8 0%,#207cca 49%,#2989d8 50%,#1e5799 100%); /* W3C */
+	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#1e5799', endColorstr='#7db9e8',GradientType=0 ); /* IE6-9 */
+}
+
+div.chattrButton.unlocked:active{
+	border-top:2px solid #1e5799;
+	border-left:2px solid #1e5799;
+	border-bottom:2px solid #7db9e8;
+	border-right:2px solid #7db9e8;
+	background: #1e5799; /* Old browsers */
+	background: -moz-linear-gradient(top,  #1e5799 0%, #2989d8 50%, #207cca 51%, #7db9e8 100%); /* FF3.6+ */
+	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#1e5799), color-stop(50%,#2989d8), color-stop(51%,#207cca), color-stop(100%,#7db9e8)); /* Chrome,Safari4+ */
+	background: -webkit-linear-gradient(top,  #1e5799 0%,#2989d8 50%,#207cca 51%,#7db9e8 100%); /* Chrome10+,Safari5.1+ */
+	background: -o-linear-gradient(top,  #1e5799 0%,#2989d8 50%,#207cca 51%,#7db9e8 100%); /* Opera 11.10+ */
+	background: -ms-linear-gradient(top,  #1e5799 0%,#2989d8 50%,#207cca 51%,#7db9e8 100%); /* IE10+ */
+	background: linear-gradient(to bottom,  #1e5799 0%,#2989d8 50%,#207cca 51%,#7db9e8 100%); /* W3C */
+	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#7db9e8', endColorstr='#1e5799',GradientType=0 ); /* IE6-9 */
+}
+
+/* LOCKED */
+div.chattrButton.locked i{
+	background: url(../../images/locked.png) no-repeat left center;
+	height:16px;
+	width:16px;
+	display: inline-block;
+	float:left;
+}
+
+div.chattrButton.locked{
+	border-bottom:2px solid #e73827;
+	border-right:2px solid #e73827;
+	border-top:2px solid #f85032;
+	border-left:2px solid #f85032;
+	background: #f85032; /* Old browsers */
+	background: -moz-linear-gradient(top,  #f85032 0%, #f16f5c 50%, #f6290c 51%, #f02f17 71%, #e73827 100%); /* FF3.6+ */
+	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f85032), color-stop(50%,#f16f5c), color-stop(51%,#f6290c), color-stop(71%,#f02f17), color-stop(100%,#e73827)); /* Chrome,Safari4+ */
+	background: -webkit-linear-gradient(top,  #f85032 0%,#f16f5c 50%,#f6290c 51%,#f02f17 71%,#e73827 100%); /* Chrome10+,Safari5.1+ */
+	background: -o-linear-gradient(top,  #f85032 0%,#f16f5c 50%,#f6290c 51%,#f02f17 71%,#e73827 100%); /* Opera 11.10+ */
+	background: -ms-linear-gradient(top,  #f85032 0%,#f16f5c 50%,#f6290c 51%,#f02f17 71%,#e73827 100%); /* IE10+ */
+	background: linear-gradient(to bottom,  #f85032 0%,#f16f5c 50%,#f6290c 51%,#f02f17 71%,#e73827 100%); /* W3C */
+	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f85032', endColorstr='#e73827',GradientType=0 ); /* IE6-9 */
+}
+
+div.chattrButton.locked:active{
+	border-top:2px solid #e73827;
+	border-left:2px solid #e73827;
+	border-bottom:2px solid #f85032;
+	border-right:2px solid #f85032;
+	background: #e73827; /* Old browsers */
+	background: -moz-linear-gradient(top,  #e73827 0%, #f02f17 29%, #f6290c 49%, #f16f5c 50%, #f85032 100%); /* FF3.6+ */
+	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#e73827), color-stop(29%,#f02f17), color-stop(49%,#f6290c), color-stop(50%,#f16f5c), color-stop(100%,#f85032)); /* Chrome,Safari4+ */
+	background: -webkit-linear-gradient(top,  #e73827 0%,#f02f17 29%,#f6290c 49%,#f16f5c 50%,#f85032 100%); /* Chrome10+,Safari5.1+ */
+	background: -o-linear-gradient(top,  #e73827 0%,#f02f17 29%,#f6290c 49%,#f16f5c 50%,#f85032 100%); /* Opera 11.10+ */
+	background: -ms-linear-gradient(top,  #e73827 0%,#f02f17 29%,#f6290c 49%,#f16f5c 50%,#f85032 100%); /* IE10+ */
+	background: linear-gradient(to bottom,  #e73827 0%,#f02f17 29%,#f6290c 49%,#f16f5c 50%,#f85032 100%); /* W3C */
+	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#e73827', endColorstr='#f85032',GradientType=0 ); /* IE6-9 */
+}
+
+.viewitem{
+	height:16px;
+}
+
+/* File Operations */
+.file-operations{
+	height:36px;
+}
+
+.operations-button{
+	border-bottom:1px solid black;
+	border-right:1px solid black;
+	border-top:1px solid gray;
+	border-left:1px solid gray;
+	display:block;
+	float:left;
+	padding:5px 5px 2px 5px;
+	vertical-align:middle;
+	-webkit-border-radius: 9px;
+	-moz-border-radius: 9px;
+	border-radius: 9px;
+	cursor:pointer;
+	margin-left:5px;
+	margin-bottom:5px;
+	background:#DEDEDE;
+	-webkit-user-select: none;
+	-moz-user-select: none;
+	user-select: none;
+	width:17.5%;
+}
+
+.operations-button:active{
+	background:#EFEFEF;
+	border-top:1px solid black;
+	border-left:1px solid black;
+	border-bottom:1px solid gray;
+	border-right:1px solid gray;
+}
+
+.operations-button > div{
+	display:block;
+	float:left;
+	position:relative;
+	bottom:2px;
+}
+
+.operations-button i{
+	display:block;
+	float:left;
+	width:16px;
+	height:16px;
+	background-size: 16px 16px !important;
+}
+
+#remove i{
+	background: url(action-images/remove.gif);
+}
+
+#rename i{
+	background: url(action-images/rename.gif);
+}
+
+#move i{
+	background: url(action-images/move.gif);
+}
+
+#copy i{
+	background: url(action-images/copy.gif);
+}
+
+#compress i{
+	background: url(action-images/compress.gif);
+}
+
+#uncompress i{
+	background: url(action-images/uncompress.gif);
+}
+
+#create_file i{
+	background: url(action-images/create_file.gif);
+}
+
+#create_folder i{
+	background: url(action-images/create_folder.gif);
+}
+
+#upload i{
+	background: url(action-images/upload.gif);
+}
+
+#send_by_email i{
+	background: url(action-images/send_by_email.gif);
+}
+
+progress:indeterminate::-moz-progress-bar {
+	background-color: gray;
+}
+

+ 6 - 0
modules/update/updating.css

@@ -0,0 +1,6 @@
+h4{
+	width:50%;
+	text-transform:uppercase;
+	text-align:left;
+	margin:0;
+}