<commit_before><?php
    class FileCacher {
        public function __construct($url, $config) {
            $this->user   = logged_in() ? Visitor::current()->login : "guest" ;
            $this->caches = CACHES_DIR.DIR."filecacher";
            $this->path   = $this->caches.DIR.sanitize($this->user);
            $this->url    = rawurldecode($url); # Percent decode for URL exclusion list comparison.
            $this->file   = $this->path.DIR.md5($this->url).".html";

            $caches_fixed = fix($this->caches, false, true);

            # If the cache directory does not exist and cannot be created, or is not writable, cancel execution.
            if ((!is_dir($this->caches) and !@mkdir($this->caches)) or !is_writable($this->caches))
                cancel_module("cacher",
                    _f("Cacher module cannot continue because <em>%s</em> is not writable.", $caches_fixed, "cacher"));

            # Remove all expired files.
            $this->remove_expired();
        }

        public function url_available() {
            return file_exists($this->file);
        }

        public function get() {
            if (DEBUG)
                error_log("SERVING cache file for ".$this->url);

            $cache = array('contents' => file_get_contents($this->file), 'headers' => array());

            if (substr_count($cache['contents'], "<feed"))
                $cache["headers"][] = "Content-Type: application/atom+xml; charset=UTF-8";

            return $cache;
        }

        public function set($value) {
            if (DEBUG)
                error_log("GENERATING cache file for ".$this->url);

            # Generate the user's directory.
            if (!file_exists($this->path))
                mkdir($this->path);

            file_put_contents($this->file, $value);
        }

        public function remove_expired() {
            foreach ((array) glob($this->caches.DIR."*".DIR."*.html") as $file) {
                if (time() - filemtime($file) > Config::current()->cache_expire)
                    @unlink($file);

                $dir = dirname($file);
                if (!count((array) glob($dir.DIR."*")))
                    @rmdir($dir);
            }
        }

        public function regenerate() {
            if (DEBUG)
                error_log("REGENERATING caches");

            foreach ((array) glob($this->caches.DIR."*".DIR."*.html") as $file)
                @unlink($file);
        }

        public function regenerate_local($user = null) {
            if (DEBUG)
                error_log("REGENERATING caches for local user ".$this->user);

            $directory = (isset($user)) ? $this->caches.DIR.$user : $this->path ;

            foreach ((array) glob($directory.DIR."*.html") as $file)
                @unlink($file);
        }

        public function remove_caches_for($url) {
            if (DEBUG)
                error_log("REMOVING caches for ".$url);

            foreach ((array) glob($this->caches.DIR."*".DIR.md5($url).".html") as $file)
                @unlink($file);
        }
    }
<commit_msg>Cacher module: simpler cancellation message<commit_after><?php
    class FileCacher {
        public function __construct($url, $config) {
            $this->user   = logged_in() ? Visitor::current()->login : "guest" ;
            $this->caches = CACHES_DIR.DIR."filecacher";
            $this->path   = $this->caches.DIR.sanitize($this->user);
            $this->url    = rawurldecode($url); # Percent decode for URL exclusion list comparison.
            $this->file   = $this->path.DIR.md5($this->url).".html";

            # If the cache directory does not exist and cannot be created, or is not writable, cancel execution.
            if ((!is_dir($this->caches) and !@mkdir($this->caches)) or !is_writable($this->caches))
                cancel_module("cacher", __("Cacher module cannot write cache files to disk.", "cacher"));

            # Remove all expired files.
            $this->remove_expired();
        }

        public function url_available() {
            return file_exists($this->file);
        }

        public function get() {
            if (DEBUG)
                error_log("SERVING cache file for ".$this->url);

            $cache = array('contents' => file_get_contents($this->file), 'headers' => array());

            if (substr_count($cache['contents'], "<feed"))
                $cache["headers"][] = "Content-Type: application/atom+xml; charset=UTF-8";

            return $cache;
        }

        public function set($value) {
            if (DEBUG)
                error_log("GENERATING cache file for ".$this->url);

            # Generate the user's directory.
            if (!file_exists($this->path))
                mkdir($this->path);

            file_put_contents($this->file, $value);
        }

        public function remove_expired() {
            foreach ((array) glob($this->caches.DIR."*".DIR."*.html") as $file) {
                if (time() - filemtime($file) > Config::current()->cache_expire)
                    @unlink($file);

                $dir = dirname($file);
                if (!count((array) glob($dir.DIR."*")))
                    @rmdir($dir);
            }
        }

        public function regenerate() {
            if (DEBUG)
                error_log("REGENERATING caches");

            foreach ((array) glob($this->caches.DIR."*".DIR."*.html") as $file)
                @unlink($file);
        }

        public function regenerate_local($user = null) {
            if (DEBUG)
                error_log("REGENERATING caches for local user ".$this->user);

            $directory = (isset($user)) ? $this->caches.DIR.$user : $this->path ;

            foreach ((array) glob($directory.DIR."*.html") as $file)
                @unlink($file);
        }

        public function remove_caches_for($url) {
            if (DEBUG)
                error_log("REMOVING caches for ".$url);

            foreach ((array) glob($this->caches.DIR."*".DIR.md5($url).".html") as $file)
                @unlink($file);
        }
    }

{'fraction_non_alphanumeric': 0.15461715412421953, 'fraction_numerical': 0.000985869208018403, 'mean_word_length': 1.8377622377622378, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 68, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2619912', 'n_tokens_mistral': 1765, 'n_tokens_neox': 1667, 'n_words': 376}