var cfg = require('../../cfg.json'); var fs = require('fs'); var http = require('http'); var https = require('https'); var mysql = require('mysql'); var bot = require('coffea')(); var uuid = require('uuid'); var crypto = require('crypto'); var path = require('path'); var exec = require('child_process').exec; var neu = true; var sql; var haDC = () => { sql = mysql.createConnection(cfg.mysql); sql.connect((err) => { if(err) setTimeout(haDC,2000); }); sql.on('error', (err) => { if(err.code === 'PROTOCOL_CONNECTION_LOST') haDC(); }); }; haDC(); cfg.server.forEach((e,i,a) => { bot.add({ "name": e.name, "host": e.host, "port": e.port, "ssl": e.ssl, "ssl_allow_invalid": e.ssl_allow_invalid, "pass": e.pass, "nick": e.nick, "username": e.username, "realname": e.realname }); console.log("Server "+e.name+" wurde geladen"); }); bot.on('motd', (e) => { console.log("motd von "+e.network+" erhalten"); bot.write('MODE f0ck +B', e.network, (c)=>{}); // Botflag }); bot.on('message', (e) => { var orig = e.message; if(orig.match(/https?:\/\/[\w-]+(\.[\w-]+)+\.?(:\d+)?(\/\S*)?/gi)) { // shitpostcatcher var tmp = orig.match(/https?:\/\/[\w-]+(\.[\w-]+)+\.?(:\d+)?(\/\S*)?/gi); // get links tmp.forEach((entry,i,a) => { var tmpdest = uuid.v1().split('-')[0]; dl(entry, "./b/"+tmpdest, (cb) => { // download item if(cb.status === true) { var tmpuser = getUser(e.user.getNick(), e.network); getCheckSum("./b/"+tmpdest+"."+cb.infos.ext, (cbcs) => { checkRepostCheckSum(cbcs, (cbcrcs) => { if(cbcrcs) { sql.query("insert into `f0ck`.`items` (`src`,`dest`,`mime`,`size`,`checksum`,`username`,`userchannel`,`usernetwork`,`stamp`,`thumb`,`active`) values (?,?,?,?,?,?,?,?,?,?,?)", [ entry, "./b/"+tmpdest+"."+cb.infos.ext, cb.infos.mime, cb.infos.size, cbcs, tmpuser['nick'], e.channel.getName(), e.network, Math.floor(new Date() / 1000), '', 0 ]).on('result', (result) => { neu = true; e.reply("https://f0ck.me/"+result.insertId+" - "+path.parse(entry).base+" ("+cb.infos.mime+", ~"+formatSize(cb.infos.size)+") from "+tmpuser['nick']+" ("+tmpuser['username']+"@"+tmpuser['hostname']+")"); }).on('error', (msg) => { e.reply(msg); }); } else { fs.unlink("./b/"+tmpdest+"."+cb.infos.ext); // delete repost e.reply("repost motherf0cker"); } }); }); } else if(cb.type == 1) e.reply(cb.msg); }); }); } else if(orig.match(/^\.user/)) { // (debug) get userinfos var tmp = getUser(e.user.getNick(), e.network); setTimeout(()=>{ e.reply(tmp); }, 1500); } }); var getUser = (u, n) => { bot.whois(u, n, (fn)=>{ }); // send whois var start = Date.now(); while(Date.now() < start + 1000) {} // block script for catch whois return bot.getUser(u, n); }; var dl = (url, dest, cb) => { var request = (url.match(/^https/)?https:http).get(url, (response) => { // type:1=post,type:2=stfu console.log(response.headers['content-type']); if(cfg.allowedMimes.hasOwnProperty(response.headers['content-type'])) { if(response.headers['content-length'] <= cfg.maxFileSize) { checkRepost(url, (cbcr) => { if(cbcr) { var file = fs.createWriteStream(dest+"."+cfg.allowedMimes[response.headers['content-type']]); response.pipe(file); file.on('finish', () => { file.close(); cb({'status':true, 'msg':'downloaded '+dest, 'type':1, 'infos':{'mime':response.headers['content-type'], 'size':response.headers['content-length'], 'ext':cfg.allowedMimes[response.headers['content-type']]}}); }); file.on('error', (err) => { fs.unlink(dest); file.close(); cb({'status':false, 'msg':err.message, 'type':1}); }); } else cb({'status':false, 'msg':'repost motherf0cker', 'type':1}); }); } else cb({'status':false, 'msg':'f0ck! your file is too big (~'+formatSize(response.headers['content-length'])+'), max '+formatSize(cfg.maxFileSize)+' allowed', 'type':1}); } else cb({'status':false, 'msg':'f0ck you', 'type':2}); }).on('error', (msg) => { cb({'status':false, 'msg':msg, 'type':2}); }); }; var checkRepost = (url, cbcr) => { sql.query("select count(*) as count from `f0ck`.`items` where `src` = ?", url, (err, rows, fields) => { cbcr((rows[0].count == 0)?true:false); }); }; var checkRepostCheckSum = (cs, cbcrcs) => { sql.query("select count(*) as count from `f0ck`.`items` where `checksum` = ?", cs, (err, rows, fields) => { cbcrcs((rows[0].count == 0)?true:false); }); }; var formatSize = (size) => { var i = Math.floor(Math.log(size) / Math.log(1024)); return (size / Math.pow(1024, i)).toFixed(2) * 1 + ' ' + ['B', 'kB', 'MB', 'GB', 'TB'][i]; }; var getCheckSum = (file, cbcs) => { var sha256sum = crypto.createHash('sha256'); var s = fs.ReadStream(file); s.on('data', (d) => { sha256sum.update(d); }); s.on('end', () => { var generated_hash = sha256sum.digest('hex'); cbcs(generated_hash); }); }; // Webserver http.createServer((req, res) => { var filePath = '.' + req.url; var url = req.url.split("/")[1]; if(filePath == './') filePath = './index.html'; console.log('request ', filePath); var extname = String(path.extname(filePath)).toLowerCase(); var contentType = 'text/html'; var mimeTypes = { '.html': 'text/html', '.js': 'text/javascript', '.css': 'text/css', '.png': 'image/png', '.jpg': 'image/jpg', '.gif': 'image/gif', '.mp3': 'audio/mpeg', '.mp4': 'video/mp4', '.webm': 'video/webm', '.css': 'text/css' }; if(filePath == "./index.html") { // mainpage sql.query("select * from `f0ck`.`items`", (err, rows, fields) => { var tmpres = "<!DOCTYPE blah><html><head><title>f0ck me!</title><link rel=\"stylesheet\" type=\"text/css\" href=\"./s/style.css\"></head><body>"; rows.forEach((e,i,a) => { tmpres += "<a href='./"+e.id+"'><img src='./t/"+e.id+".png' /></a>\n"; }); tmpres += "</body></html>"; res.writeHead(200, { 'Content-Type': 'text/html' }); res.end(tmpres, 'utf-8'); }); } else if(Number.isInteger(parseInt(url))) { // itempage sql.query("select * from `f0ck`.`items` where `id` = ? limit 1", url, (err, rows, fields) => { var tmpres = ""; rows.forEach((e,i,a) => { tmpres += "ID: "+e.id+"<br />\n"; tmpres += "src: "+e.src+"<br />\n"; tmpres += "dest: "+e.dest+"<br />\n"; tmpres += "mime: "+e.mime+"<br />\n"; tmpres += "size: "+formatSize(e.size)+"<br />\n"; tmpres += "nick: "+e.username+"<br />\n"; tmpres += "channel: "+e.userchannel+"<br />\n"; tmpres += "network: "+e.usernetwork+"<br />\n"; switch(e.mime) { case "image/png": case "image/jpeg": case "image/gif": tmpres += "<img src='"+e.dest+"' />"; break; case "video/webm": case "video/mp4": tmpres += "<video src='"+e.dest+"' autoplay controls loop></video>"; break; case "audio/mpeg": tmpres += "<audio controls src='"+e.dest+"' type='audio/mp3' autoplay></audio>"; break; } }); res.writeHead(200, { 'Content-Type': 'text/html' }); res.end(tmpres, 'utf-8'); }); } else if(filePath.match(/^\.\/(b|s|t)\/.*/)) { // file contentType = mimeTypes[extname] || 'application/octect-stream'; fs.readFile(filePath, (error, content) => { if(error) { if(error.code == 'ENOENT') { res.writeHead(200, { 'Content-Type': contentType }); res.end('404 - file not found', 'utf-8'); } else { res.writeHead(500); res.end('Sorry, check with the site admin for error: '+error.code+' ..\n'); res.end(); } } else { res.writeHead(200, { 'Content-Type': contentType, 'Content-Length': content.length }); res.end(content, 'utf-8'); } }); } else { // errorpage res.writeHead(404); res.end('404 - not found', 'utf-8'); } }).listen(cfg.webserver.port); // Thumbnailbackgroundworker setInterval(()=>{generateThumbs();}, 300000); // 5 minutes setTimeout(()=>{generateThumbs();}, 5000); // 5 seconds (start) var generateThumbs = () => { var outdir = './t/'; if(neu) { sql.query("select * from `f0ck`.`items` where `thumb` = ''", (err, rows, fields) => { rows.forEach((e,i,a) => { if(!fs.existsSync(outdir+e.id+'.png')) { exec('ffmpegthumbnailer -i'+e.dest+' -o'+outdir+e.id+'.png -a', (error) => { if(error) { //console.log(error); //bot.send("#f0ck", "failed thumbnail for "+e.id, 'n0xy'); } else { //bot.send("#f0ck", "generated thumbnail for "+e.id, 'n0xy'); } }); } }); }); } };