var fs = require('fs-extra'); var http = require('http'); var https = require('https'); var exec = require('child_process').exec; var probe = require('node-ffprobe'); var crypto = require('crypto'); var Mime = require('mime'); var bot, sql, cfg, debug; module.exports = Lib; function Lib(tbot, tsql, tcfg) { this.bot = bot = tbot; this.sql = sql = tsql; this.cfg = cfg = tcfg; this.debug = debug = true; this.admins = []; } Lib.prototype.getUser = (e, cbgu) => { var u = e.user.getNick(); var n = e.network; if(!e.user.hasOwnProperty('hostname')) { setTimeout(()=>{ bot.write('WHOIS '+u, n, () => { bot.once('data', (err, msg) => { var params; var map = []; map.push(u); if(msg.command == 'RPL_WHOISUSER') { params = msg.params.split(' '); map[u] = map[u] || {}; map[u].nick = u; map[u].username = params[2]; map[u].hostname = params[3]; map[u].realname = msg.trailing; } if(typeof(map[u]) === 'object') cbgu(map[u]); }); }); }, 100); } else { cbgu({ nick: e.user.nick, username: e.user.username, hostname: e.user.hostname, realname: e.user.realname }); } }; Lib.prototype.getUserlevel = (e, cb) => { Lib.prototype.getUser(e, (cbgu) => { var host = cbgu.username+'@'+cbgu.hostname; var lvl_channel = (cbgu.nick in e.channel.names)? cfg.level[ e.channel.names[cbgu.nick] ] : 0; var lvl_db = 0; if(host in this.admins) lvl_db = (this.admins[host].server == e.network)? this.admins[host].level : 0; cb({ 'channel': lvl_channel, 'db': lvl_db, 'level': Math.max(lvl_channel, lvl_db) }); }); }; Lib.prototype.loadUser = (cb) => { this.admins = []; sql.query("select * from `f0ck`.`user`", (err, rows, fields) => { rows.forEach((e,i,a) => { this.admins.push(e.nick); this.admins[e.vhost] = { 'id': e.id, 'nick': e.nick, 'vhost': e.vhost, 'level': e.level, 'server': e.server }; }); cb(true); }).on('error', () => { cb(false); }); } Lib.prototype.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); }); }; Lib.prototype.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); }); }; Lib.prototype.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]; }; Lib.prototype.getCheckSum = (file, cbcs) => { var sha256sum = crypto.createHash('sha256'); var s = fs.ReadStream(file); s.on('data', (d) => { sha256sum.update(d); }); s.on('end', () => { cbcs(sha256sum.digest('hex')); }); }; Lib.prototype.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) { Lib.prototype.checkRepost(url, (cbcr) => { if(cbcr) { var file = fs.createWriteStream(dest+"."+cfg.allowedMimes[response.headers['content-type']]); response.pipe(file); file.on('finish', () => { file.close(); var mime = Mime.lookup(dest+"."+cfg.allowedMimes[response.headers['content-type']]); if(cfg.allowedMimes.hasOwnProperty(mime)) { probe(dest+"."+cfg.allowedMimes[response.headers['content-type']], (err, probeData) => { if(probeData.streams[0].height !== undefined || probeData.streams[0].width !== undefined) { if(probeData.streams[0].height + probeData.streams[0].width <= cfg.minRes) cb({'status':false, 'msg':'f0ck! your shitpost is too small', 'type':1}); else 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']]}}); } else 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']]}}); }); } else cb({'status':false, 'msg':'lol, go f0ck yourself', 'type':1}); }); file.on('error', (err) => { fs.unlink(dest+"."+cfg.allowedMimes[response.headers['content-type']]); 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}); }); }; Lib.prototype.generateThumbs = () => { var outdir = './t/'; sql.query("select * from `f0ck`.`items`", (err, rows, fields) => { rows.forEach((e,i,a) => { var thumbnail = outdir+e.id+'.png'; if(!fs.existsSync(thumbnail)) { exec('ffmpegthumbnailer -i'+e.dest+' -s1024 -o'+thumbnail, (error) => { if(error) { Lib.prototype.log('failed thumbnail for '+e.id+' ('+e.mime+') 1'); fs.copySync('./s/mp3.png', thumbnail); // copy standardthumbnail } else { exec('convert '+thumbnail+' -resize "128x128^" -gravity center -crop 128x128+0+0 +repage '+thumbnail, (error) => { if(error) Lib.prototype.log('failed thumbnail for '+e.id+' ('+e.mime+') 2'); else Lib.prototype.log("generated thumbnail for "+e.id+" ("+e.mime+")"); }); } }); } }); }); }; Lib.prototype.log = (msg) => { if(debug) bot.send("#f0ck", msg, 'n0xy'); }; Lib.prototype.toggleDebug = () => { if(debug) { debug = false; return 'debugmode deactivated'; } else { debug = true; return 'debugmode activated'; } };