From 23525e3c2619721c67533cfbd8180db3ce641adb Mon Sep 17 00:00:00 2001 From: Flummi Date: Tue, 13 Sep 2016 00:39:21 +0200 Subject: [PATCH] new parser --- package.json | 4 +- src/lib.js | 67 +++++++----- src/trigger/parser.js | 237 +++++++++++++++++++++++++++++++----------- src/trigger/test.js | 8 +- src/trigger/ytdl.js | 91 ---------------- 5 files changed, 222 insertions(+), 185 deletions(-) delete mode 100644 src/trigger/ytdl.js diff --git a/package.json b/package.json index e581afc..156055d 100644 --- a/package.json +++ b/package.json @@ -9,10 +9,12 @@ "cloudscraper": "^1.4.0", "coffea": "^0.4.26", "du": "^0.1.0", + "file-type": "^3.8.0", "forever-monitor": "^1.7.0", "fs-extra": "^0.30.0", - "mime": "^1.3.4", "mysql": "^2.11.1", + "read-chunk": "^2.0.0", + "request": "^2.74.0", "swig": "^1.4.2", "uuid": "^2.0.2", "ytdl-core": "^0.7.17" diff --git a/src/lib.js b/src/lib.js index ac5d088..5099382 100644 --- a/src/lib.js +++ b/src/lib.js @@ -3,7 +3,7 @@ var http = require('http'); var https = require('https'); var exec = require('child_process').exec; var crypto = require('crypto'); -var Mime = require('mime'); +var request = require('request'); var bot, sql; @@ -103,36 +103,47 @@ Lib.prototype.generateThumbs = () => { rows.forEach((e,i,a) => { var thumbnail = outdir+'/'+e.id+'.png'; if(!fs.existsSync(thumbnail)) { - var cmd; - switch(e.mime) { - case "video/mp4": - case "video/webm": - case "audio/mpeg": - case "audio/ogg": - case "image/gif": - exec('ffmpegthumbnailer -i'+e.dest+' -s1024 -o'+thumbnail, (error) => { - if(error) { - Lib.prototype.log('failed thumbnail for '+e.id+' ('+e.mime+')'); - 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+")"); - }); - } - }); - break; - case "image/png": - case "image/jpeg": - exec('convert '+e.dest+' -resize "200x200^" -gravity center -crop 128x128+0+0 +repage '+thumbnail, (error) => { + if(e.thumb == '') { + var cmd; + switch(e.mime) { + case "video/mp4": + case "video/webm": + case "audio/mpeg": + case "audio/ogg": + case "image/gif": + exec('ffmpegthumbnailer -i'+e.dest+' -s1024 -o'+thumbnail, (error) => { + if(error) { + Lib.prototype.log('failed thumbnail for '+e.id+' ('+e.mime+')'); + 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+")"); + }); + } + }); + break; + case "image/png": + case "image/jpeg": + exec('convert '+e.dest+' -resize "200x200^" -gravity center -crop 128x128+0+0 +repage '+thumbnail, (error) => { + Lib.prototype.log((error)?'failed thumbnail for '+e.id+' ('+e.mime+')':'generated thumbnail for '+e.id+' ('+e.mime+')'); + }); + break; + } + } + else { + var dat = fs.createWriteStream(thumbnail); + request(e.thumb).pipe(dat); + dat.on('finish', () => { + dat.close(); + exec('convert '+thumbnail+' -resize "200x200^" -gravity center -crop 128x128+0+0 +repage '+thumbnail, (error) => { Lib.prototype.log((error)?'failed thumbnail for '+e.id+' ('+e.mime+')':'generated thumbnail for '+e.id+' ('+e.mime+')'); }); - break; + }); } - } }); }); diff --git a/src/trigger/parser.js b/src/trigger/parser.js index 951c5e3..cd44150 100644 --- a/src/trigger/parser.js +++ b/src/trigger/parser.js @@ -2,7 +2,11 @@ var fs = require('fs-extra'); var uuid = require('uuid'); var path = require('path'); var cloudscraper = require('cloudscraper'); -var Mime = require('mime'); +var readChunk = require('read-chunk'); +var fileType = require('file-type'); +var request = require('request'); +var ytdl = require('ytdl-core'); +var Readable = require('stream').Readable; var cfg = require('../../cfg/main.json'); module.exports = (bot, lib) => { @@ -16,71 +20,37 @@ module.exports = (bot, lib) => { if(!e.message.match(/\!ignore$/)) { var tmp = e.message.match(/https?:\/\/[\w-]+(\.[\w-]+)+\.?(:\d+)?(\/\S*)?/gi); // get links tmp.forEach((entry,i,a) => { - var tmpdest = uuid.v1().split('-')[0]; if(!entry.match(/f0ck\.me/i)) { - lib.checkRepost(entry, (cbcr) => { - if(cbcr === true) { - cloudscraper.request({ - method: 'GET', - url: entry, - encoding: null, - }, - (error, res, data) => { - if(error) - console.log('Error occurred'); - else { - var type = res.headers['content-type']; - var length = res.headers['content-length']; - var dest = './b/'+tmpdest+'.'+cfg.allowedMimes[type]; - if(cfg.allowedMimes.hasOwnProperty(type)) { - if(length <= cfg.maxFileSize) { - fs.writeFile(dest, data, (err) => { - if(!err) { - lib.getCheckSum(dest, (cbcs) => { - lib.checkRepostCheckSum(cbcs, (cbcrcs) => { - if(cbcrcs === true) { - var mime = Mime.lookup(dest); - if(cfg.allowedMimes.hasOwnProperty(mime)) { - bot.whois(e.user.getNick(), e.network, (err, cbgu) => { - lib.sql.query("insert into `f0ck`.`items` (`src`,`dest`,`mime`,`size`,`checksum`,`username`,`userchannel`,`usernetwork`,`stamp`,`active`) values (?,?,?,?,?,?,?,?,?,?)", [ - entry, - dest, - mime, - length, - cbcs, - cbgu['nick'], - e.channel.getName(), - e.network, - Math.floor(new Date() / 1000), - 0 - ]).on('result', (result) => { - lib.generateThumbs(); - e.reply("https://f0ck.me/"+result.insertId+" - "+path.parse(entry).base+" ("+mime+", ~"+lib.formatSize(length)+") from "+cbgu['nick']+" ("+cbgu['username']+"@"+cbgu['hostname']+")"); - }).on('error', (msg) => { - e.reply(msg); - }); - }); - } - else - e.reply('lol, go f0ck yourself'); - } - else - e.reply("repost motherf0cker: https://f0ck.me/"+cbcrcs); - }); - }); - } - else - e.reply(err); - }); - } - else - e.reply('f0ck! your file is too big (~'+lib.formatSize(length)+'), max '+lib.formatSize(cfg.maxFileSize)+' allowed'); - } + getLink(entry, (cb) => { + if(cb.success === true) { + fs.move(cb.file, cb.file + '.' + cb.info.ext, (err) => { + if(!err) { + bot.whois(e.user.getNick(), e.network, (err, cbgu) => { + lib.sql.query("insert into `f0ck`.`items` (`src`,`dest`,`mime`,`size`,`checksum`,`username`,`userchannel`,`usernetwork`,`stamp`,`active`,`thumb`) values (?,?,?,?,?,?,?,?,?,?,?)", [ + entry, + cb.file + '.' + cb.info.ext, + cb.info.mime, + cb.size, + cb.checksum, + cbgu['nick'], + e.channel.getName(), + e.network, + Math.floor(new Date() / 1000), + 0, + (cb.info.thumb !== null)?cb.info.thumb:'' + ]).on('result', (result) => { + lib.generateThumbs(); + e.reply("https://f0ck.me/"+result.insertId+" - "+cb.info.title+" ("+cb.info.mime+", ~"+lib.formatSize(cb.size)+") from "+cbgu['nick']+" ("+cbgu['username']+"@"+cbgu['hostname']+")"); + }).on('error', (msg) => { + e.reply(msg); + }); + }); } }); } else - e.reply('repost motherf0cker: https://f0ck.me/'+cbcr); + if(cb.msg != '') + e.reply(cb.msg); }); } }); @@ -89,4 +59,149 @@ module.exports = (bot, lib) => { }, desc: 'muh' }); + + var getLink = (url, cb) => { + var yt = /https?:\/\/(www\.)?(yotu\.be\/|youtube\.com\/)((.+\/)?(watch(\?v=|.+&v=))?(v=)?)([\w_-]{11})(&.+)?/gi; + var sc = /https?:\/\/(www\.)?(soundcloud\.com|snd\.sc)(\/\S*)(\/\S*)/gi; + lib.checkRepost(url, (cbcr) => { + if(cbcr === true) { + var tmpdest = uuid.v1().split('-')[0]; + var dat = fs.createWriteStream('./b/' + tmpdest); + var info; + + if(url.match(yt)) { // ytdl + ytdl.getInfo(url, (err, inf) => { + if(!err) { + var title = inf.title; + var iurl = inf.iurl; + try { + ytdl.downloadFromInfo(inf, { filter: (format) => { return format.container === 'webm'; } }) + .on('response', (res) => { + if(res.headers['content-length'] > cfg.maxFileSize) { + res.destroy(); + dat.close(); + fs.unlinkSync('./b/' + tmpdest); + cb({ success: false, msg: 'f0ck! your file is too big (~'+lib.formatSize(res.headers['content-length'])+'), max '+lib.formatSize(cfg.maxFileSize)+' allowed' }); + } + else { + info = { + type: 'youtube', + title: title, + mime: 'video/webm', + ext: 'webm', + thumb: iurl + }; + } + }) + .on('error', (err) => { + dat.close(); + fs.unlinkSync('./b/' + tmpdest); + cb({ success: false, msg: ex }); + }) + .pipe(dat); + } + catch(ex) { + dat.close(); + fs.unlinkSync('./b/' + tmpdest); + cb({ success: false, msg: ex }); + } + } + }); + } + else if(url.match(sc)) { // scdl + request('https://api.soundcloud.com/resolve.json?client_id=' + cfg.scclientid + '&url=' + url, (err, res, body) => { + if(!err && res.statusCode === 200) { + var data = JSON.parse(body); + request(data.stream_url + ((data.stream_url.indexOf('?') === -1)?'?':'&') + 'client_id=' + cfg.scclientid) + .pipe(dat); + info = { + type: 'soundcloud', + title: data.title, + mime: 'audio/mpeg', + ext: 'mp3', + thumb: (data.artwork_url !== null)?data.artwork_url.replace('large.jpg', 't300x300.jpg'):null + }; + } + else { + dat.close(); + fs.unlinkSync('./b/' + tmpdest); + cb({ success: false, msg: err }); + } + }); + } + else { // various + cloudscraper.request({ + method: 'GET', + url: url, + encoding: null, + }, + (err, res, data) => { + if(!err) { + var type = res.headers['content-type']; + var length = res.headers['content-length']; + if(cfg.allowedMimes.hasOwnProperty(type)) { + if(length <= cfg.maxFileSize) { + var s = new Readable + s.push(data); + s.push(null); + s.pipe(dat); + info = { + type: 'other', + title: path.parse(url).base, + mime: type, + ext: cfg.allowedMimes[type], + thumb: null + }; + } + else { + dat.close(); + fs.unlinkSync('./b/' + tmpdest); + cb({ success: false, msg: 'f0ck! your file is too big (~'+lib.formatSize(length)+'), max '+lib.formatSize(cfg.maxFileSize)+' allowed' }); + } + } + else { + dat.close(); + fs.unlinkSync('./b/' + tmpdest); + cb({ success: false, msg: '' }); + } + } + else { + dat.close(); + fs.unlinkSync('./b/' + tmpdest); + cb({ success: false, msg: err }); + } + }); + } + + dat + .on('finish', () => { + var size = dat.bytesWritten; + dat.close(); + if(size > cfg.maxFileSize) + cb({ success: false, msg: 'f0ck! your file is too big (~'+lib.formatSize(size)+'), max '+lib.formatSize(cfg.maxFileSize)+' allowed' }); + else { + lib.getCheckSum('./b/' + tmpdest, (cbcs) => { + lib.checkRepostCheckSum(cbcs, (cbcrcs) => { + if(cbcrcs === true) { + var mime = fileType(readChunk.sync('./b/' + tmpdest, 0, 262)); + if(cfg.allowedMimes.hasOwnProperty(mime.mime) || info.type === 'soundcloud') + cb({ success: true, info: info, size: size, file: './b/' + tmpdest, checksum: cbcs }); + else + cb({ success: false, msg: 'lol, go f0ck yourself ('+mime+')' }); + } + else + cb({ success: false, msg: 'repost motherf0cker: https://f0ck.me/'+cbcrcs }); + }); + }); + } + }) + .on('error', (err) => { + fs.unlinkSync('./b/' + tmpdest); + cb({ success: false, msg: err }); + }); + } + else + cb({ success: false, msg: 'repost motherf0cker: https://f0ck.me/'+cbcr }); + }); + }; }; \ No newline at end of file diff --git a/src/trigger/test.js b/src/trigger/test.js index be9fe67..8882133 100644 --- a/src/trigger/test.js +++ b/src/trigger/test.js @@ -1,12 +1,12 @@ module.exports = (bot, lib) => { lib.trigger.add({ name: 'test', - call: /^\!test/, + call: /^!test$/i, level: 0, - active: 1, + active: 0, func: (e) => { - e.reply('test the best'); + }, - desc: 'test' + desc: 'muh' }); }; \ No newline at end of file diff --git a/src/trigger/ytdl.js b/src/trigger/ytdl.js deleted file mode 100644 index f9547cc..0000000 --- a/src/trigger/ytdl.js +++ /dev/null @@ -1,91 +0,0 @@ -var fs = require('fs-extra'); -var ytdl = require('ytdl-core'); -var uuid = require('uuid'); -var cfg = require('../../cfg/main.json'); - -module.exports = (bot, lib) => { - lib.trigger.add({ - name: 'ytdl', - call: /https?:\/\/(www\.)?(yotu\.be\/|youtube\.com\/)((.+\/)?(watch(\?v=|.+&v=))?(v=)?)([\w_-]{11})(&.+)?/gi, - level: 0, - active: 1, - func: (e) => { - if(e.channel.getName() == '#f0ck' || e.channel.getName() == '#kbot-dev') { - if(!e.message.match(/\!ignore/)) { - var tmp = e.message.match(/https?:\/\/(www\.)?(yotu\.be\/|youtube\.com\/)((.+\/)?(watch(\?v=|.+&v=))?(v=)?)([\w_-]{11})(&.+)?/gi); // get links - tmp.forEach((entry,i,a) => { - var dl = true; - var tmpdest = uuid.v1().split('-')[0]; - lib.checkRepost(entry, (cbcr) => { - if(cbcr) { - ytdl.getInfo(entry, (err, info) => { - if(!err) { - var title = info.title; - var dat = fs.createWriteStream('./b/'+tmpdest+'.webm'); - try { - ytdl.downloadFromInfo(info, { filter: (format) => { return format.container === 'webm'; } }) - .on('response', (res) => { - if(res.headers['content-length'] > cfg.maxFileSize) { - res.destroy(); - dl = false; - e.reply('f0ck! your file is too big (~'+lib.formatSize(res.headers['content-length'])+'), max '+lib.formatSize(cfg.maxFileSize)+' allowed'); - } - }) - .on('error', (err) => { - //e.reply(err); - }) - .pipe( dat ); - } - catch(ex) { - e.reply(ex); - } - dat.on('finish', () => { - if(dl) { - dat.close(); - var stat = fs.statSync("./b/"+tmpdest+".webm"); - bot.whois(e.user.getNick(), e.network, (err, cbgu) => { - lib.getCheckSum("./b/"+tmpdest+".webm", (cbcs) => { - lib.checkRepostCheckSum(cbcs, (cbcrcs) => { - if(cbcrcs === true) { - lib.sql.query("insert into `f0ck`.`items` (`src`,`dest`,`mime`,`size`,`checksum`,`username`,`userchannel`,`usernetwork`,`stamp`,`active`) values (?,?,?,?,?,?,?,?,?,?)", [ - entry, - "./b/"+tmpdest+".webm", - "video/webm", - stat.size, - cbcs, - cbgu['nick'], - e.channel.getName(), - e.network, - Math.floor(new Date() / 1000), - 0 - ]).on('result', (result) => { - lib.generateThumbs(); - e.reply("https://f0ck.me/"+result.insertId+" - "+title+" (video/webm, ~"+lib.formatSize(stat.size)+") from "+cbgu['nick']+" ("+cbgu['username']+"@"+cbgu['hostname']+")"); - }).on('error', (msg) => { - e.reply(msg); - }); - } - else { - fs.unlink("./b/"+tmpdest+".webm"); // delete repost - e.reply("repost motherf0cker: https://f0ck.me/"+cbcrcs); - } - }); - }); - }); - } - else - fs.unlink('./b/'+tmpdest+'.webm'); - }); - } - }); - } - else - e.reply('repost motherf0cker'); - }); - }); - } - } - }, - desc: 'download youtubevideos' - }); -}; \ No newline at end of file