Add-on Script: Batch-add keywords to sequential files Add-on Script: Batch-add keywords to sequential files
 

News:

CPG Release 1.6.26
Correct PHP8.2 issues with user and language managers.
Additional fixes for PHP 8.2
Correct PHP8 error with SMF 2.0 bridge.
Correct IPTC supplimental category parsing.
Download and info HERE

Main Menu

Add-on Script: Batch-add keywords to sequential files

Started by jontas, June 08, 2006, 08:10:57 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

jontas

Please move this to the correct forum.

I am in the process of creating a large database of images (over 50,000), and was looking for a way to tag each image quickly and efficiently.  Since the photos in my gallery are from a digital camera, generally groups of images with sequential filenames get the same keyword.  Therefore, I set out to write a script that would allow me to add keywords to a range of images at once.

Please note--the code below is VERY SPECIFIC to my application.  Also, I am not a very good programmer, and I'm still learning.  I am sure it is not the most efficient design, however, it works.  You will not be able to cut and paste my code for your own purposes--it will take some modification before it can be applied generally.  But, it is a good starting point--if you are an inexperienced programmer faced with a similar problem, take a look at what I've done.  If you are an experienced programmer who would like to turn this into a plugin, please feel free.. you don't even have to credit me (you can if you want).  Also note--this is not a plugin--it is a script that stands alone and modifies the Coppermine database.  Anyway, I hope someone finds this useful:



<!-- I start with HTML only.. PHP comes later -->
<html>
<head>
<title>Tagging Tool</title>
</head>
<body>
<?php
// check all form entries and assign them to variables
if (isset($_POST['do'])) {
        
$do $_POST['do'];    
}

/*
I originally planned to use this, then removed it.  It is still in the HTML as a hidden input, so I left it in the PHP as well.. you can remove if you want..
*/

else {
        
$do '';
}
if (isset(
$_POST['start'])) {   // where the range of images to modify begins
        
$start $_POST['start'];
}
else {
        
$start '';
}
if (isset(
$_POST['stop'])) {   // where the range ends
        
$stop $_POST['stop'];
}
else {
        
$stop '';
}
if (isset(
$_POST['tags'])) {   // the keywords I am going to add
        
$tags $_POST['tags'];
}
else {
        
$tags '';
}

/* 
This is something specific to my application--it lets me define a city (an album in Coppermine) to run the database update on
*/

if (isset($_POST['city'])) {
        
$city $_POST['city'];
}
else {
        
$city '';
}

/*
This is just for safety--my image names all end in a 4 digit number, so here I ensure that I didn't accidentally have an extra digit
I was afraid this would modify the whole DB instead of the part I wanted.
*/

if ((strlen($start) > 4) || (strlen($stop)> 4)) {
        die(
'too many selects');
}
else {
// I didn't end up using $do, but I check for it anyway
if (!$do) {   // Here is all the HTML for the form input
        
?>

        Enter the range of images you would like to tag:<br>
        <form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
        Start:  <input type="text" name="start"><br>
        Stop:   <input type="text" name="stop"><br><br>
        Enter the tag(s) you would like to add to these images:<br>
        <textarea rows="7" cols="30" name="tags">Separate each tag with a comma.. no spaces!</textarea><br><br>
        Select a city to apply these changes to: <select name="city"><option value="sf06">SF</option><option value="at06">AT</option></select><br><br>
        <input type="submit" value="Submit" name="submit">
        <input type="hidden" name="do" value="update">
        </form>
<?php
}

// Make sure all necessary fields are entered, and then...

if ($do && $start && $stop && $tags) {
        
$tag explode(",",$tags);       // tags are entered in the form separated by a comma, so split them into an array
        
$db mysql_connect("localhost","username","password");  // connect to the db
        
mysql_selectdb("gallery",$db);   //select the right db
        
$res mysql_query("SELECT * FROM cpg147_pictures",$db);  //select all rows in the pictures table
        
while ($rows mysql_fetch_array($res)) {         // cycle through the rows and...
                
$num substr($rows['filename'],-8,4);      //store the last 4 chars of the image filename in $num
//this is because of the way my images are named.. you may need to change this
                
if (substr($rows['filename'],0,1) == "L") {
                        
$city1 "sf";
/*
Currently I only have 2 cities (albums) in my gallery.  
"SF" image filenames all begin with "L" and "AT" filenames 
begin with "I" so these two conditional check 
the first char of the filename and set the $city1 variable
*/
                
}
                elseif (
substr($rows['filename'],0,1) == "I") {
                        
$city1 "at";
                }
                
$pid $rows['pid'];  //sets $pid to the pid of the current row
 
if (($num >= $start) && ($num <= $stop) && $city == $city1) {  //if the current row image is in the range...
                                
$cur_tags $rows['keywords'];          // get any tags already assigned
                        
foreach ($tag as $j) {                    //for every new tag to be added
                                
$cur_tags $cur_tags " " $j;   //append it to any original tags
                        
}
$res1 mysql_query("UPDATE cpg147_pictures SET keywords = '$cur_tags' WHERE pid = '$pid' LIMIT 1",$db);
/*
Update the DB with the new keywords
There is a small bug here I can't figure out.. for some reason 
the first tag added back into the db contains a space in 
front of it.  If anyone can figure out why I'd be very grateful.  
(This does not seem to effect the operation of Coppermine)
*/
                        
print('I am currently adding: ' $cur_tags ' to ' $rows['filename'] . '<br>');
// Print some stuff so we know what is happening/happened.
}
}
}
}
?>



That's it.. let me know if you have any questions, comments, or criticisms.

Thanks!

Jon

edit (by Paver): Renamed subject from "New mod (sort of)" to "Add-on Script: Batch-add keywords to sequential files"

Paver

Please note that *anyone* can run this file if it is kept in a public directory.

It wouldn't be too difficult to make this into a plugin since it is a stand-alone script.  Since I've been working on the plugin documentation, I only have myself to blame for not having the documentation ready yet to link here, if you wanted to try such a task.  But as you said, it's working great for you.   8)

If you look at the beginning of most Coppermine core scripts, you'll see the following lines:
define('IN_COPPERMINE', true);
require('include/init.inc.php');
if (!GALLERY_ADMIN_MODE) cpg_die(ERROR, $lang_errors['access_denied'], __FILE__, __LINE__);


If you add such lines to your script, that should make your script admin-only. 

jontas

Thanks for the tip--I figured it would be safe because this gallery is not a public one (open to employees only), but it can't hurt to add that check.

Any idea on why the script is adding a space before the first keyword in the DB?  This is bugging me.

My grand scheme was to write a script that displayed thumbnails with a dropdown menu of (configurable) keywords below each.  However, time constraints and lack of PHP knowledge left me with this.. for the time being it will suffice.

Jon

Paver

That is part of my grand scheme as well (one of them).

The space before the keywords: this is a very common coding thing.  Replace this line:
$cur_tags = $cur_tags . " " . $j;
with this line:
$cur_tags = ($cur_tags ? ' ' : '') . $j;
Whenever you have a list of things, you need to add boundary conditions.  In this case, the boundary condition is the beginning.  If the variable is blank, don't add the space. 

Heh.  This board is "no support", but I figured this was OK, but let's not make this a habit.   ;)
If you have other support requests, please start a new thread on the support boards.