diff --git a/admin.php b/admin.php --- a/admin.php +++ b/admin.php @@ -56,27 +56,6 @@ require_once('inc/admin.inc'); return false; } - function emptySavedDir($todate = null) { - // Empty the saved_schedules directory - $dir = "saved_schedules"; - if(!is_dir($dir)) { - echo "

{$dir}
is not a valid directory! Please check your installation."; - return; - } - - // Do this the new fun php5 OO-way - foreach(new DirectoryIterator($dir) as $file) { - if(is_numeric($file->getFilename())){ - $isBeforeDate = isBeforeDate($file->getCTime(), $todate); - if(!$todate || $isBeforeDate) { - // unlink($dir . '/' . $file->getFilename()); - $date = date("Y-m-d",$file->getCTime()); - echo "

Erased file: " . $dir . '/' . $file->getFilename() . " ({$date})

"; - } - } - } - } - function checkAction() { $result = ''; if(isset($_GET['rehash'])) { @@ -93,16 +72,33 @@ require_once('inc/admin.inc'); if ($crawl_schools !== NULL) $result .= ': ' . implode(', ', $crawl_schools); } - else if(isset($_GET['purgetodate'])) { - // Purge saved schedule cache up to date - emptySavedDir($_GET['purgetodate']); - $result = 'Purged all saved schedules up to ' . $_GET['purgetodate']; - } - else if(isset($_GET['purge'])) { - // Purge the saved schedule cache - emptySavedDir(); - $result = 'Purge Complete'; - } + else if(isset($_GET['purge'])) + { + $purge_date = NULL; + if(isset($_GET['purgetodate'])) + { + $t = strptime($_REQUEST['purgetodate'], '%Y-%m-%d'); + $purge_date = mktime($t['tm_hour'], $t['tm_min'], $t['tm_sec'], $t['tm_mon'], $t['tm_mday'], $t['tm_year'] + 1900); + } + + $schedule_store = schedule_store_init(); + if (!$schedule_store) + return 'Purging saved schedules failed: unable to initialize schedule_store handle.'; + + $num_purged = schedule_store_purge_range($schedule_store, 0, $purge_date); + if ($num_purged === FALSE) + { + $result = 'Purging saved scheduled failed.'; + if (!$admin_enable_purge) + $result .= ' To enable purging saved schedules, since this is an irreversable operation, you must set $admin_enable_purge = TRUE in config.inc.'; + } + else + { + $result .= 'Purged ' . $num_purged . ' schedules'; + if ($purge_date !== NULL) + $result .= ' up to ' . $purge_date; + } + } return $result; } @@ -174,7 +170,13 @@ require_once('inc/admin.inc');

The highest saved_schedule id is .

+ * + * This file is a part of slate_permutate. + * + * slate_permutate is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * slate_permutate is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with slate_permutate. If not, see . + */ + +/** + * \file + * + * Provides a way to easily purge a number of saved schedules through + * a date range. + */ + +$inc_base = dirname(__FILE__) . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'inc' . DIRECTORY_SEPARATOR; +require_once($inc_base . 'admin.inc'); + +return main($argc, $argv); + +function main($argc, $argv) +{ + global $admin_enable_purge; + + $n = test(); + if ($n) + { + fprintf(STDERR, "%d tests failed; exiting\n", + $n); + return 1; + } + + $opts = getopt('hV:', array('all', 'max-time:', 'min-time:', 'help', 'verbosity:')); + + if (isset($opts['help']) || isset($opts['h'])) + { + usage($argv[0]); + return 0; + } + + $all = FALSE; + if (isset($opts['all'])) + $crawl = TRUE; + + foreach (array('min', 'max') as $time_var) + { + if (isset($opts[$time_var . '-time'])) + { + ${$time_var . '_time'} = strtotime($opts[$time_var . '-time']); + /* two ways of saying the thing failed -- was -1 until PHP 5.1.0 */ + if (${$time_var . '_time'} === FALSE || ${$time_var . '_time'} == -1) + { + fprintf(STDERR, "%s-time: Invalid date/time format, can't understand string: ``%s''.\n", + $time_var, $opts['min-time']); + return 1; + } + } + } + + if ($all && (isset($min_time) || isset($max_time))) + { + fprintf(STDERR, "error: Both --all and one of --max-time or --min-time were specified. These options are mutually exclusive.\n"); + return 1; + } + + if (!$all && (!isset($min_time) || !isset($max_time))) + { + if (isset($min_time) || isset($max_time)) + fprintf(STDERR, "error: If --min-time is set, --max-time must also be set and vice versa. This is to prevent accidents.\n"); + else + fprintf(STDERR, "error: Either --all or both of --min-time and --max-time must be passed to purge saved schedules.\n"); + return 1; + } + + $verbosity = 1; + if (isset($opts['verbosity'])) + $verbosity = (int)$opts['verbosity']; + if (isset($opts['V'])) + $verbosity = (int)$opts['V']; + if ($verbosity < 0 || $verbosity > 10) + { + fprintf(STDERR, "error: Invalid verbosity level: %d\n", $verbosity); + fprintf(STDERR, "\n"); + usage(); + return 1; + } + + if ($all) + { + fprintf(STDOUT, "Purging all schedules.\n"); + } + + if (!isset($min_time)) + $min_time = 0; + if (!isset($max_time)) + $max_time = NULL; + else + fprintf(STDOUT, "Purging from %s to %s.\n", + strftime("%F %T", $min_time), strftime("%F %T", $max_time)); + + $schedule_store = schedule_store_init(); + if (!$schedule_store) + { + fprintf(STDERR, "error: Unable to initialize schedule_store.\n"); + return 1; + } + $ret = schedule_store_purge_range($schedule_store, $min_time, $max_time); + if ($ret === FALSE) + { + fprintf(STDERR, "error: Unable to purge schedule_store%s.\n", + $all ? '' : ' range'); + if (!$admin_enable_purge) + fprintf(STDERR, "error: You need to set " . '$admin_enable_purge' . " in config.inc to enable purging schedules through the administration utilities.\n"); + return 1; + } + + fprintf(STDOUT, "Schedules deleted: %s\n", + $ret); + fprintf(STDOUT, "Purge successful.\n"); + + return 0; +} + + +/** + * \brief + * Display CLI interface usage. + */ +function usage($progname) +{ + fprintf(STDERR, "Usage: %s [--all] [--min-time=] [--max-time=] [--help] [-h]\n" + . "\n" + . " -h, --help Show this usage information and exit.\n" + . "\n" + . " --all Purge all saved schedules.\n" + . " --min-time Takes a date/time string after which a schedule must\n" + . " have been created to be deleted.\n" + . " --max-time Takes a date/time string before which a schedule must\n" + . " be saved to be dleted.\n" + . " -v, --verbosity Set the verbosity level. Valid range is from 0\n" + . " through 10.", + $progname); +} + diff --git a/inc/admin.inc b/inc/admin.inc --- a/inc/admin.inc +++ b/inc/admin.inc @@ -318,6 +318,50 @@ function school_cache_recreate($crawl_on return 0; } +/** + * \brief + * Purge a range of saved_schedules. + * + * \param $schedule_store + * The schedule_store handle for which a range of saved schedules + * must be deleted. + * \param $time_min + * The minimum unix timestamp for the range of schedules to be + * purged. + * \param $time_max + * The maximum unix timestamp for the range of schedules to be + * purged or NULL for no limit. + * \return + * FALSE on failure, an integer indicating the number of deleted + * saved_schedules on success. + */ +function schedule_store_purge_range($schedule_store, $time_min = 0, $time_max = NULL) +{ + global $admin_enable_purge; + + $schedule_id_max = schedule_store_getmaxid($schedule_store); + $num_deleted = 0; + + if (!$admin_enable_purge) + return FALSE; + + for ($schedule_id = 0; $schedule_id < $schedule_id_max; $schedule_id ++) + { + $filename = $schedule_store['dir'] . DIRECTORY_SEPARATOR . $schedule_id; + if (!file_exists($filename)) + continue; + + $statbuf = stat($filename); + if ($statbuf['ctime'] >= $time_min + && ($time_max === NULL || $statbuf['ctime'] <= $time_max)) + { + unlink($filename); + $num_deleted ++; + } + } + + return $num_deleted; +} /** * \brief diff --git a/inc/class.page.php b/inc/class.page.php --- a/inc/class.page.php +++ b/inc/class.page.php @@ -45,6 +45,7 @@ set_include_path(get_include_path() . PA $ga_trackers = array(); $feedback_emails = array('ez@ethanzonca.com, ngelderloos7@gmail.com, ohnobinki@ohnopublishing.net'); $use_captcha = FALSE; +$admin_enable_purge = FALSE; $config_inc = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'config.inc'; if (file_exists($config_inc)) { diff --git a/inc/config.inc.example b/inc/config.inc.example --- a/inc/config.inc.example +++ b/inc/config.inc.example @@ -78,8 +78,17 @@ /** * \brief - * Setting this variable true enables the administration page + * Setting this variable true enables the administration page * */ -/* $admin_enable = false; */ +/* $admin_enable = FALSE; */ +/** + * \brief + * Enable purging saved schedules through the admin/rehash.php + * script or web interface. + * + * Set to TRUE to enable this functionality. It is disabled by default + * because it causes irreparable information loss. + */ +/* $admin_enable_purge = FALSE; */