Added File Watcher

Cached files will now be watched for changes. Also the preprocessor and chaching will now log.
pull/4/head
Trivernis 6 years ago
parent b40b890c1b
commit e0c3feaf86

@ -32,12 +32,14 @@ This web server uses folders for every type of file (depending on the file's end
} }
] ]
} }
You can embed sass files as link elements in html-pages. The sass files will be preprocessed to css before send to clients. The result will also be cached and the sass file will be watched for changes. If changes occur, the file will be preprocessed anew on the next request to the file. If not, the cached file will be send. HTML-files will also be cached because they are also manipulated by the preprocessor. All cached files are watched for changes. I.e. if changes to the file are detected the caching function isCached returns false.
``` ```
Roadmap Roadmap
---- ----
**Done** **Done**
- SASS-Files and caching of preprocessed files
**ToDo** **ToDo**
- Mounting of folders or files on other locations (by using the config.json) - Mounting of folders or files on other locations (by using the config.json)
- a package.json because it seems to be important nowadays - a package.json because it seems to be important nowadays

@ -23,6 +23,12 @@ body
a a
color: $link-color color: $link-color
a:hover
color: lighten($link-color, 10%)
a:visited
color: darken($link-color, 10%)
h1, h2, h3, h4, h5 h1, h2, h3, h4, h5
line-height: 1.5em line-height: 1.5em
// tag-like classes // tag-like classes

@ -23,6 +23,7 @@ exports.getCached = function(filename) {
cf.last_call = Date.now(); // set the last call to now cf.last_call = Date.now(); // set the last call to now
cf.call_count += 1; // increase the call count cf.call_count += 1; // increase the call count
if (cf.data != null) return cf.data; if (cf.data != null) return cf.data;
logger.debug("Returning cached data for %s : %s", filename, cf.path);
return fs.readFileSync(cf.path); // return either the data or read the file return fs.readFileSync(cf.path); // return either the data or read the file
}; };
@ -32,21 +33,38 @@ exports.getCached = function(filename) {
* @param {String} data The data form the file * @param {String} data The data form the file
*/ */
exports.cache = function(filename, data) { exports.cache = function(filename, data) {
logger.verbose("Creating cache entry for %s", filename);
if (!fs.existsSync("./.cache")) fs.mkdirSync("./.cache"); // if the cache folder doesn't exist, create it if (!fs.existsSync("./.cache")) fs.mkdirSync("./.cache"); // if the cache folder doesn't exist, create it
let cache_fn = filename.replace(/[^\w\.]/g, "__"); // remove invalid path characters let cache_fn = filename.replace(/[^\w\.]/g, "__"); // remove invalid path characters
let count = 0; let count = 0;
while (fs.existsSync(filename + count + ".cache")) count++; // check if a file with the same name already exists and increase count while (fs.existsSync(filename + count + ".cache")) count++; // check if a file with the same name already exists and increase count
let cache_path = path.join(cache_dir, cache_fn+count+".cache"); // create the final file path. Cachedir + cached filename (without invalid) + count + .cache let cache_path = path.join(cache_dir, cache_fn+count+".cache"); // create the final file path. Cachedir + cached filename (without invalid) + count + .cache
logger.debug("Creating file %s", cache_path);
fs.writeFile(cache_path, data, (error) => { fs.writeFile(cache_path, data, (error) => {
logger.debug("Created file cache entry for %s", filename);
cache[filename] = { // create a cache-entry with the file's path when the file is written (so it won't be accessed before) cache[filename] = { // create a cache-entry with the file's path when the file is written (so it won't be accessed before)
"path": cache_path, // the last call to the file, the count of calls and an "path": cache_path, // the last call to the file, the count of calls and an
"last_call": null, // empty data field to store the file's data if the file "last_call": null, // empty data field to store the file's data if the file
"call_count": 0, // was called often "call_count": 0, // was called often
"data": null, "data": null,
"creation_time": Date.now() "creation_time": Date.now(),
"changed": false
}; };
fs.watch(filename, (eventType) => { // watch the file for changes
logger.debug("Change detected on %s", filename);
if (eventType == 'change') cache[filename].changed = true; // if the event change is detected set the change attribute to true
});
}); // write the data asynchronously to the file }); // write the data asynchronously to the file
}; };
var logger = require("winston");
/**
* Sets the logger for logging
* @param {Winston Logger} newLogger
*/
exports.setLogger = function(newLogger) {
logger = newLogger;
}
/** /**
* Returns if the file is already cached * Returns if the file is already cached
@ -59,18 +77,23 @@ exports.cache = function(filename, data) {
*/ */
exports.isCached = function(filename) { exports.isCached = function(filename) {
let cached_entry = cache[filename]; let cached_entry = cache[filename];
if (cached_entry) { if (cached_entry) { // check if the cache entry exists
if (cached_entry.path) { logger.debug("Found cache entry for %s", filename);
return fs.existsSync(cached_entry.path); if (cached_entry.changed) return false; // if a change was detected recache the file
if (cached_entry.path) { // check if the path variable is set
logger.debug("Found path entry for %s", filename)
return fs.existsSync(cached_entry.path); // return if the file exists
} }
} }
return false; logger.debug("Found no cache entry for %s", filename);
return false; // return false if the cache entry doesn't exist
} }
/** /**
* A function that dumps the config into the config file after appending the cache to it. * A function that dumps the config into the config file after appending the cache to it.
*/ */
exports.cleanup = function() { exports.cleanup = function() {
logger.verbose("Dumping cache into cache_dump file");
cache_dump["last"] = cache; cache_dump["last"] = cache;
fs.writeFileSync(config_path, JSON.stringify(cache_dump)); fs.writeFileSync(config_path, JSON.stringify(cache_dump));
} }

@ -11,6 +11,16 @@ const fs = require("fs"),
".html": "html", ".html": "html",
".htm": "hmtl" ".htm": "hmtl"
}; };
var logger = require("winston");
/**
* Sets the logger for logging
* @param {Winston Logger} newLogger
*/
exports.setLogger = function(newLogger) {
logger = newLogger;
caching.setLogger(logger);
}
/** /**
* Returns the data for the file. In some cases the data is processed or loaded from cache. * Returns the data for the file. In some cases the data is processed or loaded from cache.
@ -19,25 +29,31 @@ const fs = require("fs"),
*/ */
exports.getProcessed = function(filename) { exports.getProcessed = function(filename) {
try { try {
logger.debug("Processing File %s", filename);
var extension = utils.getExtension(filename); var extension = utils.getExtension(filename);
var data = null; var data = null;
if (caching.isCached(filename)) return caching.getCached(filename) if (caching.isCached(filename)) return caching.getCached(filename)
logger.debug("File is not cached. Processing...");
switch (pp_config[extension]) { switch (pp_config[extension]) {
case "sass": case "sass":
logger.debug("Processing sass %s", filename);
data = Buffer.from(pp_sass.renderSync({ data = Buffer.from(pp_sass.renderSync({
file: filename file: filename
}).css).toString("utf-8"); }).css).toString("utf-8");
break; break;
case "html": case "html":
logger.debug("Processing html %s", filename);
data = pp_html.formatHtml(filename); data = pp_html.formatHtml(filename);
break; break;
default: default:
logger.debug("No processor found for %s. Returning data.", filename);
return fs.readFileSync(filename); return fs.readFileSync(filename);
} }
caching.cache(filename, data); caching.cache(filename, data);
logger.debug("Cached file %s", filename);
return data; return data;
} catch (error) { } catch (error) {
console.error(error); logger.error(error);
return "Processing Error"; return "Processing Error";
} }
} }

@ -85,6 +85,7 @@ const https = require('https'),
*/ */
function main() { function main() {
try { try {
prepro.setLogger(logger);
https.createServer(options, function(req, res) { https.createServer(options, function(req, res) {
logger.verbose({'msg': 'Received request', 'method': req.method, 'url': req.url}); logger.verbose({'msg': 'Received request', 'method': req.method, 'url': req.url});

Loading…
Cancel
Save