Skip to content

Commit

Permalink
file/filesize/date check for caching as well as "latest mtime"
Browse files Browse the repository at this point in the history
  • Loading branch information
ben-xo committed May 25, 2022
1 parent 22d6115 commit a4a6f2b
Showing 1 changed file with 77 additions and 8 deletions.
85 changes: 77 additions & 8 deletions dir2cast.php
Original file line number Diff line number Diff line change
Expand Up @@ -771,6 +771,29 @@ public function getModificationTime()
}
return max($mtimes);
}

public function getTotalFileSize()
{
$sizes = array(
$this->getFileSize()
);

$common_prefix = dirname($this->getFilename()) . '/' . basename($this->getFilename(), '.' . $this->getExtension());

foreach(array(
$this->getImageFilename('jpg'),
$this->getImageFilename('png'),
$common_prefix . '.txt',
$common_prefix . '_subtitle.txt'
) as $f)
{
if(file_exists($f))
{
$sizes[] = filesize($f);
}
}
return array_sum($sizes);
}
}

class Media_RSS_Item extends RSS_File_Item implements Serializable {
Expand Down Expand Up @@ -1095,6 +1118,10 @@ class Dir_Podcast extends Podcast
protected $scanned = false;
protected $unsorted_items = array();
protected $max_mtime = 0;
protected $item_hash_list = array();
protected $item_hash;

protected $clock_offset = 0;

/**
* Constructor
Expand Down Expand Up @@ -1145,6 +1172,8 @@ protected function scan()
if(self::$EMPTY_PODCAST_IS_ERROR && 0 == $item_count)
throw new Exception("No Items found in {$this->source_dir}");

$this->calculateItemHash();

$this->scanned = true;
$this->post_scan();
$this->sort();
Expand Down Expand Up @@ -1199,6 +1228,22 @@ public function getMaxMtime()
return $this->max_mtime;
}

public function calculateItemHash()
{
sort($this->item_hash_list);
$this->item_hash = md5(implode("\n", $this->item_hash_list));
}

public function getItemHash()
{
return $this->item_hash;
}

public function setClockOffset($offset)
{
$this->clock_offset = $offset;
}

/**
* Adds file to ->unsorted_items, and updates ->max_mtime
*
Expand All @@ -1210,17 +1255,20 @@ protected function addRssFileItem(RSS_File_Item $the_item)
if($the_item->getFileSize())
{
$filemtime_media_only = $the_item->getFileTimestamp();
$filemtime_inclusive = $the_item->getModificationTime();

if((self::$MIN_FILE_AGE > 0) && $filemtime_media_only > (time() - self::$MIN_FILE_AGE))
{
// don't add files which are so new that they may still be being uploaded
return;
}

$filemtime_inclusive = $the_item->getModificationTime();

// one array per mtime, just in case several MP3s share the same mtime.
$this->unsorted_items[$filemtime_media_only][] = $the_item;
$this->updateMaxMtime($filemtime_inclusive, $the_item->getFilename());
$this->unsorted_items[$filemtime_media_only][] = $the_item;
$hashlist_mtime = $filemtime_inclusive + $this->clock_offset; // clock offset is just used in testing.
$this->item_hash_list[] = "{$hashlist_mtime}:{$the_item->getTotalFileSize()}";
}
}

Expand Down Expand Up @@ -1250,7 +1298,7 @@ protected function sort() {
}
}

unset($this->unsorted_items);
unset($this->unsorted_items);
}

protected function pre_scan() { }
Expand All @@ -1267,6 +1315,7 @@ class Cached_Dir_Podcast extends Dir_Podcast
{
protected $temp_dir;
protected $temp_file;
protected $item_hash_file;
protected $cache_date;
protected $serve_from_cache;

Expand All @@ -1283,10 +1332,11 @@ class Cached_Dir_Podcast extends Dir_Podcast
public function __construct($source_dir, $temp_dir)
{
$this->temp_dir = $temp_dir;
$safe_source_dir = str_replace(array('/', '\\'), '_', $source_dir);
$safe_source_name = preg_replace('/[^\w]/', '_', dirname($source_dir) . '/' . basename($source_dir) );

// something unique, safe, stable and easily identifiable
$this->temp_file = rtrim($temp_dir, '/') . '/' . md5($source_dir) . '_' . $safe_source_dir . '.xml';
$this->temp_file = rtrim($temp_dir, '/') . '/' . md5($source_dir) . '_' . $safe_source_name . '.xml';
$this->item_hash_file = rtrim($temp_dir, '/') . '/' . md5($source_dir) . '_' . $safe_source_name . '__item_hash.txt';

parent::__construct($source_dir);
}
Expand All @@ -1308,15 +1358,24 @@ public function init()
{
self::$DEBUG && print("Cache file is older than " . self::$MIN_CACHE_TIME . " seconds\n");

$this->scan(); // sets $this->max_mtime
$previous_item_hash = "";
if(file_exists($this->item_hash_file))
$previous_item_hash = file_get_contents($this->item_hash_file);

$this->scan(); // sets $this->max_mtime and $this->item_hash
if( $this->cache_is_stale($cache_date, $this->max_mtime) )
{
self::$DEBUG && print("Cache is stale (cache file mtime: $cache_date, max mtime: {$this->max_mtime}). Uncaching\n");
$this->uncache();
}
elseif( $previous_item_hash != $this->item_hash )
{
self::$DEBUG && print("Cache has changed (before: $previous_item_hash, after: {$this->item_hash}). Uncaching\n");
$this->uncache();
}
else
{
self::$DEBUG && print("Cache is not stale (cache file mtime: $cache_date, max mtime: {$this->max_mtime}). Renewing\n");
self::$DEBUG && print("Cache is not stale (cache file mtime: $cache_date, max mtime: {$this->max_mtime} and previous hash {$previous_item_hash} and hash {$this->item_hash}). Renewing\n");
$this->renew();
}
}
Expand Down Expand Up @@ -1384,6 +1443,7 @@ public function generate()
{
$output = parent::generate();
file_put_contents($this->temp_file, $output); // save cached copy
file_put_contents($this->item_hash_file, $this->item_hash);
$this->serve_from_cache = true;
}

Expand Down Expand Up @@ -1586,7 +1646,7 @@ public static function bootstrap(array $SERVER, array $GET, array $argv)
define('INI_FILE', $ini_file_name);
}

$cli_options = getopt('', array('help', 'media-dir::', 'media-url::', 'output::', 'dont-uncache', 'min-file-age::', 'debug', 'ignore-dir2cast-mtime'));
$cli_options = getopt('', array('help', 'media-dir::', 'media-url::', 'output::', 'dont-uncache', 'min-file-age::', 'debug', 'ignore-dir2cast-mtime', 'clock-offset::'));
if($cli_options) {
if(isset($cli_options['help'])) {
print "Usage: php dir2cast.php [--help] [--media-dir=MP3_DIR] [--media-url=MP3_URL] [--output=OUTPUT_FILE]\n";
Expand All @@ -1596,6 +1656,7 @@ public static function bootstrap(array $SERVER, array $GET, array $argv)
// [--min-file-age=MIN_FILE_AGE]
// [--debug]
// [--ignore-dir2cast-mtime]
// [--clock-offset=CLOCK_OFFSET]

exit;
}
Expand Down Expand Up @@ -1627,6 +1688,10 @@ public static function bootstrap(array $SERVER, array $GET, array $argv)
{
define('IGNORE_DIR2CAST_MTIME', true);
}
if(!defined('CLOCK_OFFSET') && isset($cli_options['clock-offset']))
{
define('CLOCK_OFFSET', (int)$cli_options['clock-offset']);
}
}

if(!defined('MIN_CACHE_TIME'))
Expand Down Expand Up @@ -1833,6 +1898,9 @@ public static function defaults(array $SERVER)
if(!defined('DEBUG'))
define('DEBUG', false);

if(!defined('CLOCK_OFFSET'))
define('CLOCK_OFFSET', 0);

// Set up factory settings for Podcast subclasses
Dir_Podcast::$EMPTY_PODCAST_IS_ERROR = !defined('CLI_ONLY') || !CLI_ONLY;
Dir_Podcast::$RECURSIVE_DIRECTORY_ITERATOR = RECURSIVE_DIRECTORY_ITERATOR;
Expand Down Expand Up @@ -2069,6 +2137,7 @@ function main($args)
);

$podcast = new Locking_Cached_Dir_Podcast(MP3_DIR, TMP_DIR);
$podcast->setClockOffset(CLOCK_OFFSET);
$dispatcher = new Dispatcher($podcast);

$dispatcher->uncache_if_forced(FORCE_PASSWORD, $_GET);
Expand Down

0 comments on commit a4a6f2b

Please sign in to comment.