247 lines
		
	
	
	
		
			6.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			247 lines
		
	
	
	
		
			6.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
		
			Executable file
		
	
	
	
	
| #!/usr/bin/node
 | |
| 
 | |
| let fs = require('fs'),
 | |
| 	path = require('path'),
 | |
| 	args = process.argv.slice(2),
 | |
| 	input = "-", // - will reperesent stdin
 | |
| 	output = "-", // - will represent stdout
 | |
| 	delimiter = ",";
 | |
| let Reset = "\x1b[0m",
 | |
| Bright = "\x1b[1m",
 | |
| Dim = "\x1b[2m",
 | |
| Underscore = "\x1b[4m",
 | |
| Blink = "\x1b[5m",
 | |
| Reverse = "\x1b[7m",
 | |
| Hidden = "\x1b[8m",
 | |
| 	
 | |
| FgBlack = "\x1b[30m",
 | |
| FgRed = "\x1b[31m",
 | |
| FgGreen = "\x1b[32m",
 | |
| FgYellow = "\x1b[33m",
 | |
| FgBlue = "\x1b[34m",
 | |
| FgMagenta = "\x1b[35m",
 | |
| FgCyan = "\x1b[36m",
 | |
| FgWhite = "\x1b[37m",
 | |
| 	
 | |
| BgBlack = "\x1b[40m",
 | |
| BgRed = "\x1b[41m",
 | |
| BgGreen = "\x1b[42m",
 | |
| BgYellow = "\x1b[43m",
 | |
| BgBlue = "\x1b[44m",
 | |
| BgMagenta = "\x1b[45m",
 | |
| BgCyan = "\x1b[46m",
 | |
| BgWhite = "\x1b[47m";
 | |
| 
 | |
| if( args[0] == "-h" || args[0] == "--help" ){
 | |
| 	console.log(FgGreen + "Aquarius Redirects (beta)" + Reset);
 | |
| 	console.log();
 | |
| 	console.log("This takes a csv file from stdinput or a given filename as the first parameter");
 | |
| 	console.log();
 | |
| 	console.log(FgGreen + "Example:" + Reset);
 | |
| 	console.log("aquarius-redirects test.csv \t\t\t This will take each line of a csv file and turn it into a redirect");
 | |
| 	console.log("cat test.csv | aquarius-redirects\t\t This is equivilent to the above");
 | |
| 	console.log("echo \"/test/, /test-2/\" | aquarius-redirects\t This will create a redirect from /test/ to /test-2/");
 | |
| 	console.log();
 | |
| 	console.log();
 | |
| 	console.log();
 | |
| 	console.log(FgGreen + "The CSV File" + Reset);
 | |
| 	console.log();
 | |
| 	console.log("Each row in the CSV file should respond to a redirect.");
 | |
| 	console.log("\t 1. From URL");
 | |
| 	console.log("\t 2. To URL");
 | |
| 	console.log("\t 3. Redirect Type");
 | |
| 	console.log("\t 4. Exact ");
 | |
| 	console.log();
 | |
| 	console.log(FgGreen + "E.g." + Reset);
 | |
| 	console.log("/page-1/                    |  /page-2/                |       |        ");
 | |
| 	console.log("/about-us/meet-the-team/    |  /meet-the-team/         |       |        ");
 | |
| 	console.log("/about-us/meet-the-team/*/  |  /meet-the-team/*/       |       |  true  ");
 | |
| 	console.log("//google.com/page-1/        |  /page-2/                |       |        ");
 | |
| 	console.log("//google.com/page-1/        |  //google.co.uk/page-2/  |  302  |  true  ");
 | |
| 	console.log("//google.com/*/             |  //google.co.uk/*/       |       |        ");
 | |
| 	console.log();
 | |
| 	console.log(FgGreen + "From URL" + Reset);
 | |
| 	console.log("This is the URL that should be redirected away from");
 | |
| 	console.log("It can optionally contain a * symbol do denote a wildcard expresion");
 | |
| 	console.log("For exmaple, /about-us/*/ will redirect from any child page of /about-us/");
 | |
| 	console.log("");
 | |
| 	console.log(FgGreen + "To URL" + Reset);
 | |
| 	console.log("This is the URL that should be redirected to");
 | |
| 	console.log("It can optionally contain an * symbol if you contained one in the From URL");
 | |
| 	console.log("For exmaple, /about-us/*/ in From and /about/*/ in To will redirect all child pages of about us to the corresponding page under about");
 | |
| 	console.log("");
 | |
| 	console.log(FgGreen + "Redirect Type" + Reset);
 | |
| 	console.log("This is the redirect type");
 | |
| 	console.log("This is optional and contains the responce code that will be sent with the redirection request.");
 | |
| 	console.log("The default is 301 which is a permenant redirect. You might want to make this 302 which implies a temporary redirect");
 | |
| 	console.log("");
 | |
| 	console.log(FgGreen + "Exact" + Reset);
 | |
| 	console.log("This denotes whether the trailing slash should be optional on the from URL");
 | |
| 	console.log("This defualts to false");
 | |
| 	console.log("If true, the From url /about-us != /about-us/ ");
 | |
| 	
 | |
| 
 | |
| 	process.exit(0);
 | |
| }
 | |
| 
 | |
| if(args[0] != undefined && args[0] != ""){
 | |
| 	input = args[0];
 | |
| }
 | |
| 
 | |
| if(input == "-" ) { // We are reading from stdin
 | |
| 	process.stdin.setEncoding('utf-8');
 | |
| 	let contents = "";
 | |
| 	process.stdin.on("readable", () => {
 | |
| 		let back = process.stdin.read();
 | |
| 		if (back != null){
 | |
| 			contents = contents + back;
 | |
| 		}
 | |
| 	});
 | |
| 	process.stdin.on("end", () => {
 | |
| 		doRedirects(contents);
 | |
| 	});
 | |
| 	//console.error("I haven't implemented stdin yet");
 | |
| 	//process.exit(1);
 | |
| } else {
 | |
| 
 | |
| 	fs.readFile(input, {encoding: 'utf-8'}, function(err,data){
 | |
| 		if (!err) {
 | |
| 			doRedirects(data)
 | |
| 		} else {
 | |
| 			console.log(err);
 | |
| 			process.exit(1);
 | |
| 		}
 | |
| 	});
 | |
| }
 | |
| 
 | |
| function doRedirects(data){
 | |
| 	let lines = data.split("\n");
 | |
| 	for (let i = 0; i < lines.length; i++){
 | |
| 		lines[i] = lines[i].split(",");
 | |
| 		for (let j = 0; j < lines[i].length; j++){
 | |
| 			lines[i][j] = lines[i][j].replace(/^\s*/g,"");
 | |
| 			lines[i][j] = lines[i][j].replace(/\s*$/g,"");
 | |
| 		}
 | |
| 		if (lines[i].length > 1){
 | |
| 			let from = lines[i][0],
 | |
| 				to = lines[i][1],
 | |
| 				type = lines[i][2] || 301,
 | |
| 				exact = lines[i][3] || false;
 | |
| 			if( from == to ){
 | |
| 				process.stdout.write("### No need to redirect " + from + "to itself ###\n\n");
 | |
| 				continue;
 | |
| 			}
 | |
| 			let redirect = individualRedirect(from,to,type,exact);
 | |
| 			process.stdout.write("###Redirect from "+from+" to "+to+"###\n");
 | |
| 			process.stdout.write(redirect+"\n");
 | |
| 			process.stdout.write("\n");
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| function individualRedirect(from, to, type, exact){
 | |
| 	var ret = "";
 | |
| 	if(!from){
 | |
| 		throw new Error( "You must have a from url" );
 | |
| 	}
 | |
| 	if(!to){
 | |
| 		throw new Error( "You must have a to url" );
 | |
| 	}
 | |
| 	if(!type){
 | |
| 		type = 301;
 | |
| 	}
 | |
| 	if(!exact){
 | |
| 		exact = false;
 | |
| 	}
 | |
| 	if(typeof exact == "string" && exact.toLowerCase() != "true"){
 | |
| 		exact = false;
 | |
| 	}
 | |
| 	from = splitURL_(from);
 | |
| 	if(from.domain != ""){
 | |
| 		ret += "RewriteCond %{HTTP_HOST} ^" + escape_(from.domain) + "$\n";
 | |
| 	}
 | |
| 	for (var i in from.queries){
 | |
| 		ret += "RewriteCond %{QUERY_STRING} (^|&)" + i + ((from.queries[i] !== undefined)?("\=" + from.queries[i]):"") + "($|&)\n";
 | |
| 	}
 | |
| 	ret += "RewriteRule " + doFrom_(from.path,exact) + " " + doTo_(to) + " " + doRewrite_(type);
 | |
| 	return ret;
 | |
| }
 | |
| 
 | |
| function doFrom_(from,exact){
 | |
| 	if(from[0]=="/"){
 | |
| 		from = "^" + from.substring(1,from.length);
 | |
| 	}
 | |
| 	if(!exact){
 | |
| 		if(from[from.length-1]=="/"){
 | |
| 			from = from+"?";
 | |
| 		} else {
 | |
| 			from = from + "\/?";
 | |
| 		}
 | |
| 	}
 | |
| 	from = escape_(from);
 | |
| 	return from + "$";
 | |
| }
 | |
| 
 | |
| function escape_(url){
 | |
| 	return url.replace(/\//g,"\\\/")
 | |
| 		.replace(/\-/g,"\\\-")
 | |
| 		.replace(/\./g,"\\\.")
 | |
| 		.replace(/\*/g,"(.*?)");
 | |
| }
 | |
| 
 | |
| function doTo_(to){
 | |
| 	if(to[0]!="/" && to.indexOf("//")==-1){
 | |
| 		to = "/"+to;
 | |
| 	}
 | |
| 	to = to.replace(/\*/g,"$1");
 | |
| 	if(to.indexOf(" ") != -1){
 | |
| 		to = '"' + to + '"';
 | |
| 	}
 | |
| 	return to;
 | |
| }
 | |
| 
 | |
| function doRewrite_(type){
 | |
| 	return "[L,R="+type+"]";
 | |
| }
 | |
| 
 | |
| function splitURL_(url){
 | |
| 	ret = {
 | |
| 		protocol:"",
 | |
| 		domain:"",
 | |
| 		path:"",
 | |
| 		queries:{}
 | |
| 	};
 | |
| 
 | |
| 	var p=url.indexOf("//");
 | |
| 	if(p!=-1){
 | |
| 		//Gets the protocol
 | |
| 		ret.protocol = url.substring(0,p-1);
 | |
| 		//Removes up to and including the protocol
 | |
| 		url = url.substring(p+2)
 | |
| 
 | |
| 		var d = url.indexOf("/");
 | |
| 		if(d!=-1){
 | |
| 			//gets the domain
 | |
| 			ret.domain = url.substring(0,d);
 | |
| 			url=url.substring(d);
 | |
| 		} else {
 | |
| 			ret.domain = url;
 | |
| 			url = "";
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	var q=url.indexOf("?");
 | |
| 	if(q!=-1){
 | |
| 		queries = url.substring(q+1).split("&");
 | |
| 		for (var i = 0; i<queries.length; i++){
 | |
| 			ret.queries[queries[i].split("=")[0]] = queries[i].split("=")[1];
 | |
| 		}
 | |
| 
 | |
| 		url = url.substring(0,q);
 | |
| 	}
 | |
| 
 | |
| 	ret.path=url;
 | |
| 
 | |
| 
 | |
| 	return ret;
 | |
| }
 |