/usr/bin/ansel-garbage-collection is in php-horde-ansel 3.0.3+debian0-3.
This file is owned by root:root, with mode 0o755.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129  | #!/usr/bin/php
<?php
/**
 * This script looks for images in the VFS that have no pointer in the
 * database. Any non-referenced images it finds get moved to a garbage
 * folder in Ansel's VFS directory.
 *
 * Make sure to run this as a user who has full permissions on the VFS
 * directory.
 *
 * @author Ben Chavet <ben@horde.org>
 * @author Michael J Rubinsky <mrubinsk@horde.org>
 * @pacakge Ansel
 */
if (file_exists(__DIR__ . '/../../ansel/lib/Application.php')) {
    $baseDir = __DIR__ . '/../';
} else {
    require_once 'PEAR/Config.php';
    $baseDir = PEAR_Config::singleton()
        ->get('horde_dir', null, 'pear.horde.org') . '/ansel/';
}
require_once $baseDir . 'lib/Application.php';
Horde_Registry::appInit('ansel', array('cli' => true));
$parser = new Horde_Argv_Parser(
    array(
        'usage' => '%prog [--options]',
        'optionList' => array(
            new Horde_Argv_Option(
                '-m',
                '--move',
                array(
                    'help' => 'Actually move dangling images to GC folder.',
                    'default' => false,
                    'action' => 'store_true'
                )
            ),
            new Horde_Argv_Option(
                '-v',
                '--verbose',
                array(
                    'help' => 'Verbose output',
                    'default' => false,
                    'action' => 'store_true'
                )
            )
        )
    )
);
list($opts, $args) = $parser->parseArgs();
$vfs = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Vfs')->create();
$vfspath = '.horde/ansel/';
$garbagepath = $vfspath . 'garbage/';
$hash = $vfs->listFolder($vfspath, null, false, true);
sort($hash);
$styles = $injector->getInstance('Ansel_Storage')->getHashes();
$count = 0;
foreach ($hash as $dir) {
    if ($dir['name'] == 'garbage') {
        continue;
    }
    try {
        $images = $vfs->listFolder($vfspath . $dir['name'] . '/full/');
    } catch (Horde_Vfs_Exception $e) {
        continue;
    }
    foreach ($images as $image) {
        $image_id = strpos($image['name'], '.') ? substr($image['name'], 0, strpos($image['name'], '.')) : $image['name'];
        $result = $ansel_db->selectValue('SELECT 1 FROM ansel_images WHERE image_id = ' . (int)$image_id);
        if (!$result) {
            if (!$count && !$vfs->isFolder($vfspath, 'garbage')) {
                $vfs->createFolder($vfspath, 'garbage');
            }
            $count++;
            if ($opts['verbose']) {
                $cli->message($vfspath . $image['name'] . ' -> ' . $garbagepath . $image['name'], 'cli.info');
            }
            if ($opts['move']) {
                try {
                    $vfs->move($vfspath . $dir['name'] . '/full/', $image['name'], $garbagepath);
                } catch (Horde_Vfs_Exception $e) {
                    $cli->fatal($e->getMessage());
                }
                // These may fail, and it's ok if they do. Might not exist.
                try {
                    $vfs->deleteFile($vfspath . $dir['name'] . '/screen/', $image['name']);
                    $vfs->deleteFile($vfspath . $dir['name'] . '/thumb/', $image['name']);
                    $vfs->deleteFile($vfspath . $dir['name'] . '/mini/', $image['name']);
                    foreach ($styles as $style) {
                        $vfs->deleteFile($vfspath . $dir['name'] . '/' . $style . '/', $image['name']);
                    }
                } catch (Horde_Vfs_Exception $e) {
                }
                // Might also fail if directories are not empty...and that's
                // to be expected.
                try {
                    $vfs->deleteFolder($vfspath . $dir['name'], 'full');
                    $vfs->deleteFolder($vfspath . $dir['name'], 'screen');
                    $vfs->deleteFolder($vfspath . $dir['name'], 'thumb');
                    $vfs->deleteFolder($vfspath . $dir['name'], 'mini');
                    foreach ($styles as $style) {
                        $vfs->deleteFolder($vfspath . $dir['name'], $style);
                    }
                    $vfs->deleteFolder($vfspath, $dir['name']);
                } catch (Horde_Vfs_Exception $e) {
                }
            }
        }
    }
}
if ($count) {
    $msg = 'Found dangling images';
    if ($opts['move']) {
        $msg .= ' and moved $count to ' . $garbagepath . '.';
    } else {
        $msg .= ', run this script with --move to clean them up.';
    }
    $cli->message($msg, 'cli.success');
} else {
    $cli->message('No cleanup necessary.', 'cli.success');
}
 |