Really? Thanks!Nphyx":3gg93u0c said:*laugh* No not working on it working with it - as in to put together a code snippet In any case, I'll throw something your way this week.
PearDB? I dunno anything about PearDB but I do see an option in my control panel which allows me to install something called 'PHP PEAR Packages'. That's all.Nphyx":1qinet24 said:Doh, actually this time I did forget about it >< I wrote up some of it, I need to know whether you have pearDB library on your server or not so I can tack in the database connectivity. If not no worries, I just can't reuse a particular handy piece of code. I'll check back for your reply ASAP so we can throw it together.
Oh, also, I need to know your file structure so I can set up the dbase structure properly, i.e.:
/system/locale/rom.zip
or
/system/year/rom.zip
Or whatever, and also if you have any particular expectations about the database structure. Right now I have it set up to use:
- id - a standard 36 char UUID
- name - the name of the rom minus the file extension (must be unique)
- path - path to the file
- extension - file name extension
- system - what system it runs on
Anything else you need in there or any specific needs, let me know.
It all fits in one little php script you can run from command line or chron or whatever (though for testing I have it set to automatically start in the current directory, remind me if I forget that and it goes crazy and scans your whole system). It's configurable so you can tag in file types at your leisure easily from an array toward the top of the file, you'll see it in there when I post it.
Any other ideas / requests?
pearDB is a nice little library that streamlines interaction with a database. If you install the PEAR packages it should come with them.Mortar":ru3cehny said:PearDB? I dunno anything about PearDB but I do see an option in my control panel which allows me to install something called 'PHP PEAR Packages'. That's all.
It will pick apart the path to the file and get the system from that. I will use a regular expression for it, with that structure what I'll do is have it find the last word between two slashes for the system, then the last word before a ., then the string after the dot, anchored to the end of the file, so it'll be /([^/]*)/(.*)\.(.*)$ if you want to test that over at http://www.quanetic.com/regex.php. You could throw some of your filenames in there and see if they all match up properly if you want.As for the file structure, it'll just be 'files/roms/[system]/rom.zip.
I do have two questions, how does the script define the system? Does it look at the directory in which the rom is placed?
The extension, e.g. zip, rar, iso, cso, rom, whatever. You can add as many file extensions as you like to the script, there's a spot for it.Also, what exactly do you mean by 'extension - file name extension'?
Thanks a lot for doing this! :D
php rom.php [path]
<?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` (
`uuid` 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 ( `uuid` )
) ENGINE = MYISAM ;
***********************************
*/
class Config {
/* CONFIGURATION */
const HOSTNAME = "localhost"; // Your host here
const DATABASE = "romtest"; // Name of your database
const USERNAME = "romtest"; // Database username
const PASSWORD = "romtest"; // Database password
const TABLE = "roms"; // 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) {
$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 $uuid;
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']);
var_dump($m);
$this->uuid = $this->makeUuid();
$this->name = $thefile['name'];
$this->path = addslashes($thefile['path']);
$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 UUID
*
* @author Anis uddin Ahmad <admin@ajaxray.com>
* @param string an optional prefix
* @return string the formatted uuid
*/
function makeUuid($prefix = "")
{
$chars = md5(uniqid(rand()));
$uuid = substr($chars,0,8).'-';
$uuid .= substr($chars,8,4).'-';
$uuid .= substr($chars,12,4).'-';
$uuid .= substr($chars,16,4).'-';
$uuid .= substr($chars,20,12);
return $prefix . $uuid;
}
function load ($uuid) {
$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 UUID (??WTF??)");
$row = mysql_fetch_assoc($result);
$this->uuid = $row['uuid'];
$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(
'uuid' => $this->uuid,
'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 == 'uuid' || $key == 'name') {} // don't update UUIDs 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` (`uuid`, `name`, `path`, `system`, `extension`, `size`) VALUES ('%s', '%s', '%s', '%s', '%s', '%s')",
$this->config->table(),
$this->uuid,
$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";
}
}
?>
I'm not sure where to put this syntax. Can you help me?Nphyx":goouuioj said:Okay, here's a provisional copy. You'll find the SQL necessary to generate the database in the top and the configuration options right below that, it seems like you know PHP enough to figure it out from here. The syntax for use is
Code:php rom.php [path]
-- Starting Search -- Starting in /home/romstati/public_html.
Warning: Missing argument 1 for Config::__construct(), called in /home/romstati/public_html/rom.php on line 315 and defined in /home/romstati/public_html/rom.php on line 45
Warning: Invalid argument supplied for foreach() in /home/romstati/public_html/rom.php on line 322
Warning: Invalid argument supplied for foreach() in /home/romstati/public_html/rom.php on line 322
Warning: Invalid argument supplied for foreach() in /home/romstati/public_html/rom.php on line 322
Warning: Invalid argument supplied for foreach() in /home/romstati/public_html/rom.php on line 322
Warning: Invalid argument supplied for foreach() in /home/romstati/public_html/rom.php on line 322
Warning: Invalid argument supplied for foreach() in /home/romstati/public_html/rom.php on line 322
Warning: Invalid argument supplied for foreach() in /home/romstati/public_html/rom.php on line 322
Warning: Invalid argument supplied for foreach() in /home/romstati/public_html/rom.php on line 322
Warning: Invalid argument supplied for foreach() in /home/romstati/public_html/rom.php on line 322
Warning: Invalid argument supplied for foreach() in /home/romstati/public_html/rom.php on line 322
Warning: Invalid argument supplied for foreach() in /home/romstati/public_html/rom.php on line 322
Warning: Invalid argument supplied for foreach() in /home/romstati/public_html/rom.php on line 322
Warning: Invalid argument supplied for foreach() in /home/romstati/public_html/rom.php on line 322
Warning: Invalid argument supplied for foreach() in /home/romstati/public_html/rom.php on line 322
Warning: Invalid argument supplied for foreach() in /home/romstati/public_html/rom.php on line 322
Warning: Invalid argument supplied for foreach() in /home/romstati/public_html/rom.php on line 322
Warning: Invalid argument supplied for foreach() in /home/romstati/public_html/rom.php on line 322
Warning: Invalid argument supplied for foreach() in /home/romstati/public_html/rom.php on line 322
Warning: Invalid argument supplied for foreach() in /home/romstati/public_html/rom.php on line 322
Warning: Invalid argument supplied for foreach() in /home/romstati/public_html/rom.php on line 322
Warning: Invalid argument supplied for foreach() in /home/romstati/public_html/rom.php on line 322
Warning: Invalid argument supplied for foreach() in /home/romstati/public_html/rom.php on line 322
Warning: Invalid argument supplied for foreach() in /home/romstati/public_html/rom.php on line 322
Warning: Invalid argument supplied for foreach() in /home/romstati/public_html/rom.php on line 322
And at the bottom a ton of lines like this one:
array(4) { [0]=> string(32) "/gba/Pokemon Dragonstone (U).zip" [1]=> string(3) "gba" [2]=> string(23) "Pokemon Dragonstone (U)" [3]=> string(3) "zip" }
Thanks!
I'm not sure where to put this syntax. Can you help me?Nphyx":2p90irnz said:Okay, here's a provisional copy. You'll find the SQL necessary to generate the database in the top and the configuration options right below that, it seems like you know PHP enough to figure it out from here. The syntax for use is
Code:php rom.php [path]
The first error is my bad, I did a quick change to the script last night and forgot about that little thing, at around line 45 changeI am getting this error though:
Code:-- Starting Search -- Starting in /home/romstati/public_html. ............
function __construct($debug) {
function __construct($debug = false) {
var_dump($m);
if($this->config->debug) var_dump($m);
P.S. It seems to add the files to the database nonetheless, although it grabs files from other directories as well, such as my include and forums directory. That's not right, is it?
php rom.php "/home/romestati/files"
php /home/romstati/files/rom.php "/home/romstati/files/"
Yeah I did it like that intentionally so you could get the path to the file directly from the database for the site. However if you want to change it, you can change:Also, the path entered in the DB is the full path. Isn't it possible for the script to only get the path from the files' directory and up? For example, instead of '/home/romstati/public_html/files/roms/nes/3-D Batt...', it should enter 'nes/3-D Batt...'. And the name shows up with the extension at the end, wasn't it supposed to hide it?
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->uuid = $this->makeUuid();
$this->name = $thefile['name'];
$this->path = addslashes($thefile['path']);
$this->system = $m[1];
$this->extension = $thefile['extension'];
$this->size = $thefile['size'];
$this->config = clone $theconfig; // Prevent us from accidentally overwriting global 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->uuid = $this->makeUuid();
$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
}
Thanks in advance. :lol:
$this->uuid = $this->makeUuid();
<dl><dt>File Size:</dt><dd><?php echo number_format(($rom['size']/1048576), 2) ?>mb</dd></dl>
$this->size = $thefile['size'];
$this->size = number_format($thefile['size']/1048576, 2);