webからなんか投稿してsqliteに保存してTwitterにバックアップ的に投げるやつのモックアップ

https://github.com/ayziao/ns2015
に清書してる的な

```js:mp.js
//システム関連
var sys  = require('sys');
var os   = require('os');
var fs   = require('fs');
var path = require('path');

var zlib = require('zlib');

//HTTP関連
var http       = require('http');
var url        = require('url');
var qs         = require('querystring');
var formidable = require('formidable');
var oauth = require('oauth');

//DB
var sqlite3 = require('sqlite3').verbose();

//webサービスライブラリ
var twitter = require('twitter');
var twitter_update_with_media = require('./lib/twitter_update_with_media');
var Gyazo  = require('gyazo-api');

//定数とか TODO 設定ファイルに逃す？
var PORT = 80;
var USER = 'node';
var URL_BASE = '/';

var hostname = os.hostname() || '127.0.0.1';

var contentType = {
	html: 'text/html' ,
	htm: 'text/html' ,
	js: 'text/javascript' ,
	css: 'text/css' ,
	gif: 'image/gif' ,
	jpeg: 'image/jpeg' ,
	jpg: 'image/jpeg' ,
	jpe: 'image/jpeg' ,
	png: 'image/png' ,
	ico: 'image/vnd.microsoft.icon' ,
	txt: 'text/plain'
}; 

var twit = new twitter({
		consumer_key        : 'consumer_key',
		consumer_secret     : 'consumer_secret',
		access_token_key    : 'access_token_key',
		access_token_secret : 'access_token_secret'
});

var twit2 = new twitter({
		consumer_key        : 'consumer_key',
		consumer_secret     : 'consumer_secret',
		access_token_key    : 'access_token_key',
		access_token_secret : 'access_token_secret'
});

var tuwm = new twitter_update_with_media({
		consumer_key: 'consumer_key',
		consumer_secret: 'consumer_secret',
		token: 'token',
		token_secret: 'token_secret'
});

var twitrt = new twitter({
		consumer_key        : 'consumer_key',
		consumer_secret     : 'consumer_secret',
		access_token_key    : 'access_token_key',
		access_token_secret : 'access_token_secret'
});

var twitay = new twitter({
		consumer_key        : 'consumer_key',
		consumer_secret     : 'consumer_secret',
		access_token_key    : 'access_token_key',
		access_token_secret : 'access_token_secret'
});

var twitxt = new twitter({
		consumer_key        : 'consumer_key',
		consumer_secret     : 'consumer_secret',
		access_token_key    : 'access_token_key',
		access_token_secret : 'access_token_secret'
});

var twitest = new twitter({
		consumer_key        : 'consumer_key',
		consumer_secret     : 'consumer_secret',
		access_token_key    : 'access_token_key',
		access_token_secret : 'access_token_secret'
});

var tuwmtest = new twitter_update_with_media({
		consumer_key: 'consumer_key',
		consumer_secret: 'consumer_secret',
		token: 'token',
		token_secret: 'token_secret'
});

var db = new sqlite3.Database('db.sqlite3');

db.on("trace", function(sql) {
  console.log(sql);
});

/**
 * 日付をフォーマットする
 * @param  {Date}   date     日付
 * @param  {String} [format] フォーマット
 * @return {String}          フォーマット済み日付
 */
var formatDate = function (date, format) {
	if (!format) format = 'YYYY-MM-DD hh:mm:ss.SSS';
	format = format.replace(/YYYY/g, date.getFullYear());
	format = format.replace(/MM/g, ('0' + (date.getMonth() + 1)).slice(-2));
	format = format.replace(/DD/g, ('0' + date.getDate()).slice(-2));
	format = format.replace(/hh/g, ('0' + date.getHours()).slice(-2));
	format = format.replace(/mm/g, ('0' + date.getMinutes()).slice(-2));
	format = format.replace(/ss/g, ('0' + date.getSeconds()).slice(-2));
	if (format.match(/S/g)) {
		var milliSeconds = ('00' + date.getMilliseconds()).slice(-3);
		var length = format.match(/S/g).length;
		for (var i = 0; i < length; i++) format = format.replace(/S/, milliSeconds.substring(i, i + 1));
	}
	return format;
};

var gyazo_client = new Gyazo('GyazoKey');

//投稿画面HTML
var html = (function () {/*
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<meta name="viewport" content="width=device-width">
		<title>投稿フォーム__user__</title>
        <link rel="stylesheet" type="text/css" href="./css.css" />
        <link rel="icon" href="/@__user__/favicon.png" type="image/png"/>
		<script type="text/javascript">
			var key = "none";
			var sbmit = false;
			
			function mojilen(str){
				document.getElementById('msg1').innerHTML="<span style='font-weight: bold;color:blue ;'>"+str.length+"</span>文字 " + key;
			}
			
		</script>
	</head>
	
	
	<body>
		<h1>__user__</h1>
		<form action="__urlbase__@__user__/" method="POST" enctype="multipart/form-data">
			<textarea id="box" style="width:100%;" rows="4" name="t" onKeyup="mojilen(value);"></textarea>
			tag<input type="text" name="tags">
			<input id="btn" type="submit" name="submit" value="post" style="width: 100px;height: 60px;font-size: 2em;">
			<input type="file" name="file">
			<input type="hidden" name="user" value="__user__">
			<span id="msg1">文字数</span><br>
		</form>	
		
		
		<script type="text/javascript">
			
			var textbox=document.getElementById('box');
			var submitButton=document.getElementById('btn');
			
			textbox.addEventListener('keydown',
				function(e){
					key = e.which;
					if(sbmit==false&&e.metaKey&&e.which==13) {
						submitButton.click();
						sbmit = true;
					}
				}
				
			,false)
		</script>

		__timeline__
		
	</body>
	
	</html>
*/}).toString().match(/[^]*\/\*([^]*)\*\/\}$/)[1];


var tweet_respons = function (err,res) {
	if (err) {
		console.log('tweet_respons');
		console.log(err);
	} else {
		tweet_log(res);
	}
};

var tweet_log = function (res) {
	var dt = new Date(res.created_at );
	console.log(
		'tweet_log : ' +
		formatDate(dt,'YYYY-MM-DD hh:mm:ss') + ' ' +
		'user:' + res.user.id_str + ' ' +
		'id:' + res.id_str +
		' ' + res.text.replace(/[\n\r]/g,"\\n")
	);
};

function requestFromUser(request){
	var host = request.headers.host
	var arrayOfStrings = host.split('.niascape.');

	if (arrayOfStrings.length == 2){
		return arrayOfStrings[0];
	} else {
		var atsplit = request.url.split('@');
		if (atsplit.length == 2){
			return atsplit[1].split('/')[0];
		} else {
			return '';
		}
	}
}

function date2identifier(date){
	var tmpdate = date === undefined ? new Date() : date;
	var time = process.hrtime();
	var microtime = ("00000000"+time[1]).slice(-9,-3);
	return formatDate(tmpdate,'YYYYMMDDhhmmss' + microtime);
}

function timelinekumitate(rows){
	var timeline = '<div>';
	var day = '';
	var gyou = 'guusuu';
	rows.forEach(function(row){
		if(gyou == 'guusuu'){
			gyou = 'kisuu';
		} else {
			gyou = 'guusuu';
		}
		if(day != formatDate(new Date(row.datetime),'YYYY-MM-DD')){
			day = formatDate(new Date(row.datetime),'YYYY-MM-DD');
			timeline = timeline + '<h5>' + day + '</h5>' ;
		}

		timeline = timeline + '<div class="'+ gyou +'"><span class="time">' + formatDate(new Date(row.datetime),'hh:mm:ss') + '</span> ' + row.body + ' ' + row.tags.replace( "twitter_posted" , "" ) + "</div>\n";
	});
	return timeline + '</div>';;
}

function httpget(request,response){
	var user = requestFromUser(request);
	var staticpath = 'static';

	if(user != ''){
		staticpath = staticpath + '/' + user;
	}

    var userstaticpath = staticpath + request.url.replace('/@' + user , '');

	fs.readFile( userstaticpath, function (err, buf) {
		if (err) { //静的ファイル無し
//			console.log(err);
		    console.log(request.url);
			if(user == ''){
				user = 'test';
			}
			var outhtml = html.split("__user__").join(user).split("__urlbase__").join(URL_BASE);

			db.serialize(function(){
				var sql = "SELECT * FROM basedata WHERE user = '"+ user +"' AND tags NOT LIKE '% gyazo_posted %' ORDER BY identifier DESC LIMIT 100";
				db.all(sql, function(err, rows){
					if (!err) {
						var timeline = timelinekumitate(rows);

					}
					response.writeHead(200, {'Content-Type': 'text/html ; charset=UTF-8', 'content-encoding': 'gzip'});

	                buf = new Buffer(outhtml.split("__timeline__").join(timeline) , 'utf-8');
	                zlib.gzip(buf, function(_, result){
	                        response.end(result);
	                });
				}); 
//			    console.log(sql);
			});
		} else { //静的ファイルありの場合そのまま出力
			fs.stat(userstaticpath,  function (err, stats) {
				var etag = stats.mtime + stats.size;
//				console.log(err);
//				console.log(stats.mtime);
//				console.log(request.headers['if-none-match']);

				if( request.headers['if-none-match'] === etag ) {
					console.log(userstaticpath + ' 304 Not Modified');
					response.writeHead(304, {"Content-Type": contentType[path.extname(request.url).replace(".", '')]});
					response.end();
				} else {
					if(contentType[path.extname(request.url).replace(".", '')].indexOf('text/') == 0){
						response.writeHead(200, {
							"Content-Type": contentType[path.extname(request.url).replace(".", '')] + ";charset=UTF-8" ,
							'content-encoding': 'gzip',
							'ETag': etag
						});
		                zlib.gzip(buf, function(_, result){
		                        response.end(result);
		                });
						console.log(userstaticpath + ' 200 OK gzip');
					} else {
						response.writeHead(200, {
							"Content-Type": contentType[path.extname(request.url).replace(".", '')],
							'ETag': etag
						});
						response.end(buf);
						console.log(userstaticpath + ' 200 OK');
					}
				}


			});
		}
	});
}

function httppost(request,response){
	var form = new formidable.IncomingForm();
	var user = requestFromUser(request);

	if(user == ''){
		response.writeHead(302, {"location": URL_BASE + "@" + user + '/'});
		response.end();
		return ;
	}

	form.parse(request, function( err, fields, files) {
		if(typeof fields.t != "undefined" && fields.t !== "" ){

			var body = fields.t.trim();

			var tags = fields.tags.trim().split(" ");

			var tagstring = '';
			if(fields.tags.trim() != ''){
				tagstring = ' #' + tags.join(" #")
			}
			
			if(files.file.name !== ''){ //画像付き投稿の場合
				gyazo_client.upload(files.file.path)
				.then(function(res){
					console.log(files.file.name + ' ' +res.data.permalink_url + ' ' + res.data.url);
					console.log(res.data);

					var date1 = new Date();
					var identifier1 = date2identifier(date1) ;

					db.run("INSERT INTO basedata (user,identifier,datetime,title,tags,body) VALUES (?,?,?,?,?,?)",
						[ user ,
						 identifier1 ,
						 formatDate(date1,'YYYY-MM-DD hh:mm:ss') ,
						 identifier1 ,
						 ' gyazo_posted ',
						 JSON.stringify(res.data)
						] ,
						function(err) {
							console.log(err);
						}
					);


					if(user == 'rog'){
						tuwm.post(body + tagstring, res.data.url, function(err, response) {
							if (err) {
								console.log(err);
							} 
							else {
								var res_body = JSON.parse(response.body);
								tweet_log(res_body);
								twit2.updateStatus(JSON.parse(response.body).text + ' ' + res.data.permalink_url, tweet_respons);
								if(JSON.parse(response.body).text.match(/#猫写真/)){
									twitrt.createFavorite({id :res_body.id_str} , function (err,res) {
										if (err) {
											console.log(err);
										} else {
											var dt = new Date(res.created_at );
											console.log(
												'fav ' + 
												formatDate(dt,'YYYY-MM-DD hh:mm:ss') + ' ' +
												'user:' + res.user.id_str + ' ' +
												'id:' + res.id_str +
												' ' + res.text.replace(/[\n\r]/g,"\\n")
											);
										}
									});
									twitrt.retweetStatus(res_body.id_str , tweet_respons);
								}
							}
						});
					} else if(user == 'test'){
						tuwmtest.post(body + tagstring, res.data.url, function(err, response) {
							if (err) {
								console.log(err);
							} 
							else {
								var res_body = JSON.parse(response.body);
								tweet_log(res_body);
								twitest.updateStatus(JSON.parse(response.body).text + ' ' + res.data.permalink_url, tweet_respons);
							}
						});
					}

					var date2 = new Date();
					var identifier2 = date2identifier(date2) ;

					var tags2 = tagstring + ' twitter_posted with_image:' + identifier1 + ' ';

					db.run("INSERT INTO basedata (user,identifier,datetime,title,tags,body) VALUES (?,?,?,?,?,?)",
						[ user ,
						 identifier2 ,
						 formatDate(date2,'YYYY-MM-DD hh:mm:ss') ,
						 identifier2 ,
						 tags2,
						 body
						] ,
						function(err) {
							console.log(err);
						}
					);
					
				})
				.catch(function(err){
						console.error(err.stack);
				});
			}
			else { //画像なし
				db.serialize(function(){
					var date = new Date();
					var identifier = date2identifier(date) ;

					db.run("INSERT INTO basedata (user,identifier,datetime,title,tags,body) VALUES (?,?,?,?,?,?)",
						[ user ,
						 identifier ,
						 formatDate(date,'YYYY-MM-DD hh:mm:ss') ,
						 identifier ,
						 tagstring + ' twitter_posted ',
						 body
						] ,
						function(err) {
							console.log(err);
						}
					);
				});
				if(user == 'a-o'){
					twitay.updateStatus(body + tagstring, tweet_respons);
				}else if(user == 'txt'){
					twitxt.updateStatus(body + tagstring, tweet_respons);
				}else if(user == 'test'){
					twitest.updateStatus(body + tagstring, tweet_respons);
				}else{
					twit.updateStatus(body + '.' + tagstring, tweet_respons);
					twit2.updateStatus(body + tagstring, tweet_respons);
				}
			}
		}
		console.log(fields);
	});
	
	var arrayOfStrings = request.headers.host.split('.niascape.');
	if(arrayOfStrings.length == 2){
		response.writeHead(302, {"location": URL_BASE });
	}else{
		response.writeHead(302, {"location": URL_BASE + "@" + user + '/'});
	}
	response.end();
}

http.createServer(function (request, response) {
	if(request.method=='POST') {
		httppost(request,response);
	} 
	else if(request.method == 'GET') {
		httpget(request,response);
	}
}).listen(PORT, hostname, function () {
    console.log('change user');
    process.setuid(USER);
});

console.log('Server running at http://' + hostname + ':' + PORT + '/');