https://github.com/ayziao/ns2015
に清書してる的な
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 + '/');