<?php
/**
* rom.php
*
* scans a filesystem for files matching a given extension and enters them into a database
* @author Justen Robertson
* @license GNU/GPL
* @version 0.5
* @updated 5.25.2008
* @note supports up to 1024/256.8 as path/filename.ext according to dbase spec
*
********* SQL DBASE ****************
CREATE TABLE `roms` (
`id` CHAR( 36 ) NOT NULL ,
`name` VARCHAR( 256 ) NOT NULL ,
`path` VARCHAR( 1024 ) NOT NULL ,
`extension` VARCHAR( 8 ) NOT NULL ,
`system` VARCHAR( 64 ) NOT NULL ,
`size` INT UNSIGNED NOT NULL ,
PRIMARY KEY ( `id` )
) ENGINE = MYISAM ;
***********************************
*/
class Config {
/* CONFIGURATION */
const HOSTNAME = "-"; // Your host here
const DATABASE = "-"; // Name of your database
const USERNAME = "-"; // Database username
const PASSWORD = "-"; // Database password
const TABLE = "-"; // Name of table in database (in provided SQL, "roms");
var $file_types = Array( // File types to scan for, add more here if you like
'iso',
'cso',
'zip',
'rar',
'rom'
);
var $debug = false; // set to true to get debug results
/* END CONFIG */
function __construct($debug = false) {
$this->debug = $debug;
}
function host() {
return Config::HOSTNAME;
}
function dbase() {
return Config::DATABASE;
}
function user() {
return Config::USERNAME;
}
function pass() {
return Config::PASSWORD;
}
function table() {
return Config::TABLE;
}
function fileTypes() {
return $this->file_types;
}
function dbConnect() {
$comm = mysql_connect($this->host(), $this->user(), $this->pass()) or trigger_error(mysql_error(),E_USER_ERROR);
return $comm;
}
}
class Rom {
private $id;
private $name;
private $path;
private $extension;
private $system;
private $size;
private $config;
function __construct($thefile, $theconfig) {
ereg('.([^\\^/]*).([^\\^/]*)\.(.*)$', $thefile['path'], $m) or die ('System could not be determined for '.$thefile['path']);
if($this->config->debug) var_dump($m);
$this->name = $m[2];
$this->path = addslashes($m[0]);
$this->system = $m[1];
$this->extension = $thefile['extension'];
$this->size = $thefile['size'];
$this->config = clone $theconfig; // Prevent us from accidentally overwriting global config
}
/**
* Generates an id
*
* @author Anis uddin Ahmad <admin@ajaxray.com>
* @param string an optional prefix
* @return string the formatted id
*/
function makeid($prefix = "")
{
$chars = md5(uniqid(rand()));
$id = substr($chars,0,8).'-';
$id .= substr($chars,8,4).'-';
$id .= substr($chars,12,4).'-';
$id .= substr($chars,16,4).'-';
$id .= substr($chars,20,12);
return $prefix . $id;
}
function load ($id) {
$dbase = $this->config->dbConnect();
$query = "SELECT * FROM `".$this->config->table()."` WHERE `id` = `$id` LIMIT 1 1";
$result = mysql_query($query, $dbase) or die (mysql_error());
if (mysql_num_rows($result) > 1) die ("Error: duplicate id (??WTF??)");
$row = mysql_fetch_assoc($result);
$this->id = $row['id'];
$this->name = $row['name'];
$this->path = addslashes($row['path']);
$this->system = $row['extension'];
$this->extension = $row['extension'];
$this->size = $row['size'];
mysql_free_result($result);
if($debug) echo 'Load'.$this->name.' from id: '.$this->id.': SUCCESS';
}
function save() {
$dbase = $this->config->dbConnect();
mysql_select_db($this->config->dbase(), $dbase);
$status = false; // whether the rom exists in the database, false = its new
$query = "SELECT * FROM `".$this->config->table()."` WHERE `name` LIKE '".$this->name."'";
if($this->config->debug) echo $query."\n";
$result = mysql_query($query, $dbase) or die (mysql_error());
if (mysql_num_rows($result)) { // Check whether we already saved this rom, and if so whether it's been updated
$status = "exists";
$current = mysql_fetch_assoc($result);
$new = Array(
'id' => $this->id,
'name' => $this->name,
'path' => stripslashes($this->path),
'system' => $this->system,
'extension' => $this->extension,
'size' => $this->size
);
foreach ($current as $key => $value) { // check if anything has been changed
if ($new[$key] != $value) {
if ($key == 'id' || $key == 'name' || $key == 'count' || $key == 'total' || $key == 'rate') {} // don't update ids or names, that's bad mkay
else if ($updates) {
$status = "updated"; // set update if anything has been updated
$updates .= ", `".$key."`='".$new[$key]."'";
}
else {
$status = "updated"; // set update if anything has been updated
$updates = "`".$key."`='".$new[$key]."'";
}
}
}
}
switch ($status) {
case false :
$query = sprintf( "INSERT INTO `%s` (`id`, `name`, `path`, `system`, `extension`, `size`) VALUES ('%s', '%s', '%s', '%s', '%s', '%s')",
$this->config->table(),
$this->id,
$this->name,
$this->path,
$this->system,
$this->extension,
$this->size
);
if($this->config->debug) echo $query."\n";
mysql_query($query, $dbase) or die (mysql_error());
return "saved";
case "updated" :
//if ($this->config->debug) echo "\nTrying to set $updates.";
$query = sprintf( "UPDATE `%s` SET %s WHERE `name` = '".$this->name."'",
$this->config->table(),
$updates
);
if($this->config->debug) echo $query."\n";
mysql_query($query, $dbase) or die (mysql_error());
if ($this->config->debug) echo "Updated ".$this->name;
return "updated";
case "exists" :
if ($this->config->debug) echo "Did not update ".$this->name.": no changes\n";
return "made no changes";
default :
if ($this->config->debug) die ("MALFORMED \$update in Rom::save() for ".$this->name." : $update");
}
}
}
// ------------ lixlpixel recursive PHP functions -------------
// scan_directory_recursively( directory to scan, filter )
// expects path to directory and optional an extension to filter
// of course PHP has to have the permissions to read the directory
// you specify and all files and folders inside this directory
// ------------------------------------------------------------
// to use this function to get all files and directories in an array, write:
// $filestructure = scan_directory_recursively('path/to/directory');
// to use this function to scan a directory and filter the results, write:
// $fileselection = scan_directory_recursively('directory', 'extension');
function scan_directory_recursively($directory, $filter=FALSE)
{
// if the path has a slash at the end we remove it here
if(substr($directory,-1) == '/')
{
$directory = substr($directory,0,-1);
}
// if the path is not valid or is not a directory ...
if(!file_exists($directory) || !is_dir($directory))
{
// ... we return false and exit the function
return FALSE;
// ... else if the path is readable
}elseif(is_readable($directory))
{
// we open the directory
$directory_list = opendir($directory);
// and scan through the items inside
while (FALSE !== ($file = readdir($directory_list)))
{
// if the filepointer is not the current directory
// or the parent directory
if($file != '.' && $file != '..')
{
// we build the new path to scan
$path = $directory.'/'.$file;
// if the path is readable
if(is_readable($path))
{
// we split the new path by directories
$subdirectories = explode('/',$path);
// if the new path is a directory
if(is_dir($path))
{
// add the directory details to the file list
$directory_tree[] = array(
'path' => $path,
'name' => end($subdirectories),
'kind' => 'directory',
// we scan the new path by calling this function
'content' => scan_directory_recursively($path, $filter));
// if the new path is a file
} elseif(is_file($path))
{
// get the file extension by taking everything after the last dot
$extension = end(explode('.',end($subdirectories)));
// if there is no filter set or the filter is set and matches
if($filter === FALSE || $filter == $extension)
{
// add the file details to the file list
$directory_tree[] = array(
'path' => $path,
'name' => end($subdirectories),
'extension' => $extension,
'size' => filesize($path),
'kind' => 'file');
}
}
}
}
}
// close the directory
closedir($directory_list);
// return file list
return $directory_tree;
// if the path is not readable ...
}else{
// ... we return false
return FALSE;
}
}
// ------------------------------------------------------------
echo " -- Starting Search --\n";
if ($argc > 2) {
echo "You passed ".$_SERVER['argc']." arguments. Usage: php rom.php [/path/to/files/]\n";
}
else if ($argc == 2) {
$cur_dir = $argv[1];
}
else $cur_dir = getcwd();
echo "Starting in ".$cur_dir.".\n";
$myconfig = new Config();
$scan_results = scan_directory_recursively($cur_dir);
function clean_files($files) {
$results = Array();
foreach ($files as $key => $item) {
if ($item['kind'] == 'directory') {
if ($myconfig->debug) echo "Recursing for ".$item['name']."\n";
$results = array_merge($results, clean_files($item['content']));
}
else {
if ($myconfig->debug) echo "Adding ".$item['name']."\n";
$results []= $item;
}
}
return $results;
}
$all_roms = clean_files($scan_results);
foreach ($all_roms as $key => $item) {
if (in_array($item['extension'], $myconfig->fileTypes())) {
if($myconfig->debug) echo "Found ".$item['name'];
$therom = new Rom($item, $myconfig);
$result = $therom->save();
if($myconfig->debug) echo " and ".$result."\n";
}
}
?>