From 845bc1fa18caa2c3a75bd45db162151c08e749d4 Mon Sep 17 00:00:00 2001 From: foldericon Date: Fri, 9 Nov 2012 19:42:42 +0100 Subject: [PATCH] - new feature: aliases - new feature: perform - improved settings dialog - many many bug fixes --- .version | 1 + JIRC.js | 13 +- README | 18 +-- README.txt | 26 ++-- lib/IRC.js | 31 +++- public/classes.js | 358 +++++++++++++++++++++++++++++++++++++++----- public/index.html | 80 +++++++++- public/main.css | 99 +++++++++++- public/main.js | 40 ++++- scripts/.dontremove | 0 10 files changed, 579 insertions(+), 87 deletions(-) create mode 100644 .version delete mode 100644 scripts/.dontremove diff --git a/.version b/.version new file mode 100644 index 0000000..660ad2a --- /dev/null +++ b/.version @@ -0,0 +1 @@ +v0.9-rc1 diff --git a/JIRC.js b/JIRC.js index 09541de..512b7d1 100644 --- a/JIRC.js +++ b/JIRC.js @@ -36,11 +36,19 @@ var http = require('http'), url = require('url'), fs = require('fs'), static = require('node-static'), + getyt = require('request'), file = new(static.Server)('./public', { cache: 7200, headers: {'X-Hello':'World!'} }), httpServer = http.createServer(function(request, response) { var queryData = ""; request.on('data', function(data) { var path = url.parse(request.url).pathname; + if(path=="/youtube"){ + queryData += data; + if(queryData.length > 1e6) { + response.writeHead(413, {'Content-Type': 'text/plain'}); + request.connection.destroy(); + } + } if(path=="/resume"){ queryData += data; if(queryData.length > 1e6) { @@ -58,8 +66,8 @@ var http = require('http'), } }); - request.addListener('end', function () { - var path = url.parse(request.url).pathname; + request.addListener('end', function () { + var path = url.parse(request.url).pathname; if(path=="/emoticons"){ var emoticons = fs.readFileSync( __dirname + '/public/images/emoticons/Emoticons.plist', 'utf8' @@ -76,6 +84,7 @@ var http = require('http'), response.writeHead(200, {"Content-Type": "application/json"}); response.end(JSON.stringify(global.settings)); if(queryData) { + console.log(queryData); global.settings=JSON.parse(queryData); } } else{ diff --git a/README b/README index b29838f..f7da8a5 100644 --- a/README +++ b/README @@ -15,6 +15,13 @@ but please send me your improvements. Changelog --------- +v0.9-rc1 +- new feature: aliases +- new feature: perform +- improved settings dialog +- many many bug fixes + +v0.9-beta2 - Connection-Settings will be saved now using local storage - Colors (and color stripping) are now working correctly (0000002, 0000009) @@ -32,7 +39,6 @@ Known Issues - No error-handling in the backend - No error-handling in UI-dialogs -- Wrong size of user-list while changing size - Only one connection per time allowed - Not multi-user ready @@ -43,14 +49,8 @@ Browser Support - Tested Browsers: Firefox 16 Safari 6 - to be continued ... - -- Browsers that should work: - Chrome 14+ - Firefox 7+ - Safari 5+ - Opera ? - Internet Explorer 9+ + Opera 12.02 + Chrome 22 Installation diff --git a/README.txt b/README.txt index 5513e40..f10b586 100644 --- a/README.txt +++ b/README.txt @@ -15,6 +15,13 @@ but please send me your improvements. Changelog --------- +v0.9-rc1 +- new feature: aliases +- new feature: perform +- improved settings dialog +- many many bug fixes + +v0.9-beta2 - Connection-Settings will be saved now using local storage - Colors (and color stripping) are now working correctly (0000002, 0000009) @@ -33,7 +40,6 @@ Known Issues - No error-handling in the backend - No error-handling in UI-dialogs - no saving of connection-settings -- Wrong size of user-list while changing size - Only one connection per time allowed - Not multi-user ready @@ -41,17 +47,11 @@ Known Issues Browser Support ---------------- -Tested Browsers: - -Firefox 16 -Safari 6 to be continued ... - -- Browsers that should work: - Chrome 14+ - Firefox 7+ - Safari 5+ - Opera ? - Internet Explorer 9+ +- Tested Browsers: + Firefox 16 + Safari 6 + Opera 12.02 + Chrome 22 Installation @@ -60,4 +60,4 @@ Installation 1. Download and install NodeJS from http://nodejs.org 2. open a terminal and cd into the JIRC-directory 3. type in "node JIRC.js" -4. that's it \ No newline at end of file +4. that's it diff --git a/lib/IRC.js b/lib/IRC.js index d14a5da..76a1ca3 100644 --- a/lib/IRC.js +++ b/lib/IRC.js @@ -99,7 +99,8 @@ var util = require('util'), _ = require('underscore'), growl = require('growl'), request = require('request'); - // var buffer, ignoredb, listeners, socket; +// irc = require('irc'); +// var buffer, ignoredb, listeners, socket; var buffer, listener, socket; socket = new net.Socket(); socket.setNoDelay(true); @@ -129,6 +130,7 @@ var util = require('util'), socket.on('data', function (data) { var newlineIdx; +// console.log(data.rawCommand+' ' +data.args.join()); data = data.replace('\r', ''); while ((newlineIdx = data.indexOf('\n')) > -1) { if (buffer.size > 0) { @@ -282,6 +284,28 @@ var util = require('util'), port = port || 6667; pass = pass || ''; global.nickname = nickname; + /* + socket = new irc.Client(host, nickname, { + autoConnect: false, + userName: sanitize(username), + realName: sanitize(nickname), + port: port, + debug: false, + showErrors: false, + autoRejoin: true, + autoConnect: true, + channels: [], + secure: false, + selfSigned: false, + certExpired: false, + floodProtection: false, + floodProtectionDelay: 1000, + stripColors: false, + channelPrefixes: "&#", + messageSplit: 512 + }); + socket.connect(); + */ socket.connect(port, host, function () { if(i==0){ if(pass) send('PASS ' + sanitize(pass)); @@ -289,12 +313,13 @@ var util = require('util'), send('USER ' + sanitize(username) + ' localhost * ' + sanitize(realname)); i=1; } - }); + }); + } this.loadScripts = function () { var i, k, script, scripts; - socket.pause(); + if(socket) socket.pause(); listeners = []; scripts = fs.readdirSync('scripts'); if (scripts) { diff --git a/public/classes.js b/public/classes.js index 7396fa7..2840d57 100644 --- a/public/classes.js +++ b/public/classes.js @@ -73,10 +73,9 @@ var Query = { } }, createWindow : function(){ - var dock_icon, win, content, panel; + var win, content, panel; panel = $$('.con_panel')[0]; - dock_icon = document.createElement("span"); - this.dock_icon = dock_icon; + this.dock_icon = document.createElement("span"); // dock_icon.className = "icon_active"; this.dock_icon.className = "icon_waiting"; panel.appendChild(dock_icon); @@ -98,9 +97,11 @@ var Query = { }); this.dock_icon.win = win; // $('cons').appendChild(panel); - content = $$('.querytemplate').first().cloneNode(true); - content.style.display = 'block'; + content = $$('.querytemplate').first().cloneNode(true); win.getContent().appendChild(content); + $$('#'+win.getContent().id+' .content').first().update(); + $$('#'+win.getContent().id+' .textbox').first().value=""; + content.style.display = 'block'; // win.show(); $(dock_icon).update(win.getTitle().split(' ')[0]); Event.observe(this.dock_icon, "mouseup", Windows.restore); @@ -129,11 +130,15 @@ var Channel = { return this; }, setTopic : function(topic) { + this.topic = topic; if(topic){ this.topic=topic; - this.win.setTitle(this.name + " - Topic: " + topic); + this.win.setTitle('
                ' + this.name + ' - Topic: ' + topic + '
'); } }, + getTopic : function() { + return this.topic; + }, setWaiting : function(mode) { if(mode == 0) { if(this.dock_icon.className == "dock_icon") @@ -433,7 +438,27 @@ var Utf8 = { connection.send(data); } IRCConnection.getSettings = function() { - settings=''; + + var obj, aliases = [], performs = [], strAliases = $$('.aliases tbody').first().innerHTML, strPerform = $$('.perform tbody').first().innerHTML; + settings = {}; + if(strAliases.match(/.+<\/tr>/)){ + for (var x=0; x.*?<\/tr>/g).length; x++){ + if(strAliases.match(/.*?<\/tr>/g)[x].match(/(.*?)<\/td>(.*?)<\/td>/)){ + obj = {}; + obj.key = strAliases.match(/.*?<\/tr>/g)[x].match(/(.*?)<\/td>(.*?)<\/td>/)[1]; + obj.value = strAliases.match(/.*?<\/tr>/g)[x].match(/(.*?)<\/td>(.*?)<\/td>/)[2]; + } + aliases.push(obj); + } + } + settings.aliases=aliases; + if(strPerform.match(/.+<\/tr>/)){ + for (var x=0; x.*?<\/tr>/g).length; x++){ + performs.push(strPerform.match(/.*?<\/tr>/g)[x].match(/(.*?)<\/td>/)[1]); + } + } + settings.perform=performs; + new Ajax.Request('/settings', { method:'post', contentType:'application/json', @@ -459,26 +484,85 @@ var Utf8 = { if(data.nma == "on") $('config')['nma'].checked = true; if(data.nmakey != "") $('config')['nmakey'].value = data.nmakey; if(data.nmapriority != "") $('config')['nmapriority'].value = data.nmapriority; - settings = data; + data.aliases = JSON.parse(data.aliases); + data.perform = JSON.parse(data.perform); + settings = data; + } else { + settings = JSON.parse(localStorage.getItem('settings')); + settings.aliases = JSON.parse(settings.aliases); + settings.perform = JSON.parse(settings.perform); + } + if(settings.aliases){ + var elmAliases = $$('.aliases tbody').first(); + if(elmAliases){ + $$('.aliases tbody').each(function(elm){ + elm.update(); + for(var x=0; x' + settings.aliases[x].key + '' + settings.aliases[x].value+ '\n'); + } + }); + $$('.aliases tbody tr').each(function(elm){ + Event.observe(elm, "mousedown", function(event) { + $$('.aliases tbody tr').each(function(tr){tr.removeClassName('selected')}); + var td = Event.element(event); debug(td.parentNode); + td.parentNode.addClassName('selected') + }); + }); + } } + if(settings.perform){ + var elmPerform = $$('.perform tbody').first(); + if(elmPerform){ + $$('.perform tbody').each(function(elm){ + elm.update(); + for(var x=0; x' + settings.perform[x] + '\n'); + } + }); + $$('.perform tbody tr').each(function(elm){ + Event.observe(elm, "mousedown", function(event) { + $$('.perform tbody tr').each(function(tr){tr.removeClassName('selected')}); + var td = Event.element(event); debug(td.parentNode); + td.parentNode.addClassName('selected') + }); + }); + } + } } - }); - + }); } IRCConnection.saveSettings = function(data) { + var obj, aliases = [], performs = [], strAliases = $$('.aliases tbody').first().innerHTML, strPerform = $$('.perform tbody').first().innerHTML; + settings = {}; + settings=data; + if(strAliases.match(/.+<\/tr>/g)){ + for (var x=0; x.+<\/tr>/gi).length; x++){ + obj = {}; + obj.key = strAliases.match(/.*?<\/tr>/g)[x].match(/(.+)<\/td>(.+)<\/td>/)[1]; + obj.value = strAliases.match(/.*?<\/tr>/g)[x].match(/(.+)<\/td>(.+)<\/td>/)[2]; + aliases.push(obj); + } + } + settings.aliases=aliases; + if(strPerform.match(/.+<\/tr>/)){ + for (var x=0; x.*?<\/tr>/g).length; x++){ + performs.push(strPerform.match(/.*?<\/tr>/g)[x].match(/(.*?)<\/td>/)[1]); + } + } + settings.perform=performs; new Ajax.Request('/settings', { method:'post', contentType:'application/json', - postBody:JSON.stringify(data), + postBody:JSON.stringify(settings), asynchronous:true, onSuccess: function (req) { - // sendInfoResponse(req.responseText); IRCConnection.getSettings(); } - }); + }); + localStorage.setItem('settings', JSON.stringify(settings)); } - IRCConnection.showSettings = function() { + IRCConnection.showSettings = function() { IRCConnection.getSettings(); Dialog.confirm($('settings').innerHTML, { className:"alphacube", @@ -492,6 +576,149 @@ var Utf8 = { showEffect:Element.show, hideEffect:Element.hide }); + + $$('.aliases tbody tr').each(function(elm){ + Event.observe(elm, "mousedown", function(event) { + $$('.aliases tbody tr').each(function(tr){tr.removeClassName('selected')}); + var td = Event.element(event); + td.parentNode.addClassName('selected') + }); + + }); + + $$('.perform tbody tr').each(function(elm){ + Event.observe(elm, "mousedown", function(event) { + $$('.perform tbody tr').each(function(tr){tr.removeClassName('selected')}); + var td = Event.element(event); + td.parentNode.addClassName('selected') + }); + + }); + + $$('.set1 .alias_edit input').each(function(elm){ + Event.observe(elm, "mouseup", function(event) { + var edit = Event.element(event); + if(edit.value=="add"){ + Dialog.confirm($('dialog_alias').innerHTML, { + className:"alphacube", + width:250, + okLabel: "save", + cancelLabel: "cancel", + ok:function() { + $$('.aliases tbody').first().update($$('.aliases tbody').first().innerHTML + "" + $F('input_alias') + "" + $F('input_cmd') +" \n"); + $$('.aliases tbody tr').each(function(elm){ + Event.observe(elm, "mousedown", function(event) { + $$('.aliases tbody tr').each(function(tr){tr.removeClassName('selected')}); + var td = Event.element(event); + td.parentNode.addClassName('selected') + }); + + }); + return true; + }, + showEffect:Element.show, + hideEffect:Element.hide + }); + } else if(edit.value=="del"){ + var x=0, a; + $$('.aliases tbody tr').each(function(tr){ + if(tr.className == "selected"){ + a=x; + tr.remove(); + } + x++; + }); + $$('.aliases tbody tr')[a].addClassName('selected'); + } else if(edit.value=="edit"){ + Dialog.confirm($('dialog_alias').innerHTML, { + className:"alphacube", + width:250, + okLabel: "save", + cancelLabel: "cancel", + ok:function() { + $$('.aliases tbody tr').each(function(tr){ + if(tr.className=="selected") { + tr.update('' + $$('.form_alias input')[0].value + '' + $$('.form_alias input')[1].value + ''); + tr.removeClassName('selected'); + } + }); + return true; + }, + showEffect:Element.show, + hideEffect:Element.hide + }); + $$('.aliases tbody tr').each(function(tr){ + if(tr.className=="selected") { + $$('.form_alias input')[0].value=tr.innerHTML.match(/(.*?)<\/td>(.*?)<\/td>/)[1]; + $$('.form_alias input')[1].value=tr.innerHTML.match(/(.*?)<\/td>(.*?)<\/td>/)[2]; + } + }); + } + }); + }); + + $$('.set1 .perform_edit input').each(function(elm){ + Event.observe(elm, "mouseup", function(event) { + var edit = Event.element(event); + if(edit.value=="add"){ + Dialog.confirm($('dialog_perform').innerHTML, { + className:"alphacube", + width:250, + okLabel: "save", + cancelLabel: "cancel", + ok:function() { + $$('.perform tbody').first().update($$('.perform tbody').first().innerHTML + "" + $F('input_perform') + "\n"); + $$('.perform tbody tr').each(function(elm){ + Event.observe(elm, "mousedown", function(event) { + $$('.perform tbody tr').each(function(tr){tr.removeClassName('selected')}); + var td = Event.element(event); + td.parentNode.addClassName('selected') + }); + + }); + return true; + }, + showEffect:Element.show, + hideEffect:Element.hide + }); + } else if(edit.value=="del"){ + var x=0, a; + $$('.perform tbody tr').each(function(tr){ + if(tr.className == "selected"){ + tr.remove(); + a=x; + } + x++; + }); + $$('.perform tbody tr')[a].addClassName('selected'); + } else if(edit.value=="edit"){ + Dialog.confirm($('dialog_perform').innerHTML, { + className:"alphacube", + width:250, + okLabel: "save", + cancelLabel: "cancel", + ok:function() { + $$('.perform tbody tr').each(function(tr){ + if(tr.className=="selected") { + tr.update('' + $$('.form_perform input')[0].value + ''); + tr.removeClassName('selected'); + } + }); + return true; + }, + showEffect:Element.show, + hideEffect:Element.hide + }); + $$('.perform tbody tr').each(function(tr){ + if(tr.className=="selected") { + $$('.form_perform input')[0].value=tr.innerHTML.match(/(.*?)<\/td>/)[1]; + } + }); + } + }); + }); + + } IRCConnection.create = function() { Dialog.confirm($('login').innerHTML, { @@ -523,7 +750,10 @@ var Utf8 = { } IRCConnection.handleInput = function(title, data) { - title = title.split(' ')[0]; +// title = title.split(' ')[0]; +// debug('TITLE ' + title); + if(getActiveChan()) title = getActiveChan().name; + else title = "status"; if (data.substring(0,1) == "/") { var cmd = data.substring(1); cmd = cmd.replace(cmd.split(' ')[0], cmd.split(' ')[0].toUpperCase()); @@ -550,6 +780,9 @@ var Utf8 = { case "PART": if(title != 'status') cmd = 'PART ' + title + ' :' + cmd.substring(5); + else + if(title.substring(0,1) == "#") cmd = 'PART ' + cmd.split(' ')[1] + ' :' + cmd.split(' ')[2]; + else cmd = ""; break; case "QUIT": IRCConnection.quit(); @@ -560,12 +793,46 @@ var Utf8 = { objQuery.win.show(); channels.push(objQuery); return; + default: + var cmds; + if(settings.aliases){ + debug('jo aliases'); + for (var x=0; x-1){ - if(objChan.name != getActiveChan.name) + if(objChan.name != getActiveChan().name) objChan.setWaiting(1); context = 'hl'; } @@ -617,7 +884,7 @@ var Utf8 = { objChan.addMessage(msg); } else{ var objQuery, objUser; - msg = stripCodes(raw.replace(/.*PRIVMSG [\w\_\-\^]+ :/, '')); + msg = stripCodes(raw.replace(/.*PRIVMSG [\w\@\.\_\-\^]+ :/, '')); if(hasQueryWithName(replyTo)){ objQuery = getChannelByName(replyTo); objUser = objQuery.user; @@ -631,7 +898,7 @@ var Utf8 = { } } if(msg.indexOf(nickname)>-1){ - if(objQuery.name != getActiveChan.name) + if(objQuery.name != getActiveChan().name) objQuery.setWaiting(1); context = 'hl'; } @@ -650,16 +917,11 @@ var Utf8 = { } } - - IRCConnection.getChannels = function() { - return channels; - } - + if (raw.match(reg2)) { // JOIN var chan = raw.replace(reg2, '').replace(/^:/, '').replace(/\s$/, ''), host = raw.match(/^:([^!]+)!([^!]+)@([\w.\-_]+)/)[0].substring(1).split('!'); var msg = ''; - debug('CHANNAME ' +chan); var objChannel; if(host[0] == nickname){ objChannel = Object.create(Channel).init(chan); @@ -759,10 +1021,11 @@ var Utf8 = { if (raw.match(/^:([^!]+)!.*TOPIC /)) { // CHANGE TOPIC var host = raw.match(/^:([^!]+)!([^!]+)@([\w.\-_]+)/)[0].substring(1).split('!'); - var arrD = raw.replace(/^:([^!]+)!.*TOPIC /, '').split(' '); - var objChannel = getChannelByName(arrD[0]); - var msg = ''; - objChannel.setTopic(arrD[1].substring(1)); + var arrM = raw.match(/^:([^!]+)!.*TOPIC (\#[\w\_\-\^]+) \:(.+)/); + debug(arrM[1] + " " + arrM[2] + " " + arrM[3]); + var objChannel = getChannelByName(arrM[2]); + var msg = ''; + objChannel.setTopic(arrM[3]); objChannel.addMessage(msg); } if (raw.match(reg8) || raw.match(/^NOTICE /)) { @@ -855,7 +1118,7 @@ var Utf8 = { // TOPIC debug('TOPIC'); var topic = raw.replace(/^\:.+\s332\ .+\ \#[\w\_\-\^]+\ \:/, ''); - var objChan = getChannelByName(raw.replace(/^:.+ 332 /, '').replace(/ :.+/, '').split(' ')[1].replace(/\s$/, '')); + var objChan = getChannelByName(raw.match(/^\:.+\s332\ .+\ (\#[\w\_\-\^]+) \:/)[1]); objChan.setTopic(stripCodes(topic)); } if(raw.match(/\:.+\s352/)){ @@ -892,11 +1155,21 @@ var Utf8 = { msg = '