diff --git a/README.md b/README.md index 78659dd..9fc417f 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,131 @@ -# nchan +# Simple lua nchan publisher -Паблишер nchan \ No newline at end of file +## Install + +``` +luarocks install nchan +``` + +## Usage + +### Channels + +***Publish message in channel*** + +``` +local channel = require('nchan.channel') + +channel.nchan.host = 'http://localhost' +channel.nchan.endpoint = 'pub' + +result,msg = channel.publish('test') + +``` + + +***Connect with Basic auth*** + +``` + local channel = require('nchan.channel') + + channel.nchan.host = 'http://localhost' + channel.nchan.endpoint = 'pub' + + channel.nchan.login = 'test' + channel.nchan.password = 'test' + + result,msg = channel.publish('test') + +``` + +***Connect with Bearer auth*** + +``` + local channel = require('nchan.channel') + + channel.nchan.host = 'http://localhost' + channel.nchan.endpoint = 'pub' + + channel.nchan.token = 'token' + + result,msg = channel.publish('test') + +``` + +***Delete channel*** + +``` +local channel = require('nchan.channel') +channel.nchan.host = 'http://localhost' +channel.nchan.endpoint = 'pub' + +result,msg = channel.delete() + +``` + +***Get channel info*** + +``` +local channel = require('nchan.channel') +channel.nchan.host = 'http://localhost' +channel.nchan.endpoint = 'pub' + +result,msg = channel.status() + +print(result) +print(msg.messages) +print(msg.requested) +print(msg.subscribers) +print(msg.last_message_id) + +``` + +Channel info also available after publishing: + +``` +local channel = require('nchan.channel') + +channel.nchan.host = 'http://localhost' +channel.nchan.endpoint = 'pub' + +result,msg = channel.publish('test') + +print(result) +print(channel.nchan.info.messages) +print(channel.nchan.info.requested) +print(channel.nchan.info.subscribers) +print(channel.nchan.info.last_message_id) + +``` + +### Groups + +***Get group info*** + +``` +local channel = require('nchan.group') +channel.nchan.host = 'http://localhost' +channel.nchan.endpoint = 'pub' + +result,msg = group.status() + +print(result) +print(msg.messages) +print(msg.requested) +print(msg.subscribers) +print(msg.last_message_id) + +``` +***Set group limits*** + +``` +local channel = require('nchan.group') +channel.nchan.host = 'http://localhost' +channel.nchan.endpoint = 'pub' + +result,msg = group.limits({ + ['max_channels']=15, + ['max_subs']=1000 +}) + +``` diff --git a/nchan-1.0-2.rockspec b/nchan-1.0-2.rockspec new file mode 100644 index 0000000..13085c2 --- /dev/null +++ b/nchan-1.0-2.rockspec @@ -0,0 +1,31 @@ +package = "Nchan" +version = "1.0-2" +source = { + url = "git://github.com/Zoviet/nchan.git", + tag = "v1.0-1" +} +description = { + summary = "Simple Lua nchan publisher and group manager", + detailed = [[ + Message publishing, channel info, channels delete, groups info and groups limits setter. + ]], + homepage = "https://github.com/Zoviet/nchan", + license = "MIT/X11" +} +dependencies = { + "lua >= 5.1, < 5.4", + "luasocket >= 2.0", + "lua-cjson >= 2.0", + "mimetypes >= 1.0" +} +external_dependencies = { + +} +build = { + type = "builtin", + modules = { + ["nchan.nchan"] = "nchan/nchan.lua", + ["nchan.channel"] = "nchan/channel.lua", + ["nchan.group"] = "nchan/group.lua" + } +} diff --git a/nchan-1.0-2.src.rock b/nchan-1.0-2.src.rock new file mode 100644 index 0000000..6942776 Binary files /dev/null and b/nchan-1.0-2.src.rock differ diff --git a/nchan/channel.lua b/nchan/channel.lua new file mode 100755 index 0000000..721c101 --- /dev/null +++ b/nchan/channel.lua @@ -0,0 +1,28 @@ + +-- Simple nchan lua client + +local _M = {} + +_M.nchan = require ('nchan.nchan') + + +function _M.publish(message) + _M.nchan.method = 'POST' + return _M.nchan.request(message) +end + +function _M.status() + _M.nchan.method = 'GET' + local result, msg = _M.nchan.request() + if result then + return true, _M.nchan.info + end + return false, msg +end + +function _M.delete() + _M.nchan.method = 'DELETE' + return _M.nchan.request() +end + +return _M diff --git a/nchan/group.lua b/nchan/group.lua new file mode 100755 index 0000000..58a91e9 --- /dev/null +++ b/nchan/group.lua @@ -0,0 +1,29 @@ + +-- Simple nchan lua client + +local _M = {} + +_M.nchan = require ('nchan.nchan') + +_M.nchan.codes = { + [200] = 'SUCCESS (group existed)', + [201] = 'CREATED (limits sets)', + [202] = 'ACCEPTED' +} + + +function _M.limits(limits) + _M.nchan.method = 'POST' + return _M.nchan.request(message) +end + +function _M.status() + _M.nchan.method = 'GET' + local result, msg = _M.nchan.request() + if result then + return true, _M.nchan.info + end + return false, msg +end + +return _M diff --git a/nchan/nchan.lua b/nchan/nchan.lua new file mode 100755 index 0000000..c6df5cd --- /dev/null +++ b/nchan/nchan.lua @@ -0,0 +1,78 @@ + +-- Simple nchan lua client + +local json = require ('cjson') +local http = require('socket.http') +local mime = require('mime') +local ltn12 = require('ltn12') + +http.TIMEOUT = 15 + +local _M = {} + +_M.host = 'http://127.0.0.1' --Nchan host +_M.port = nil --Nchan port +_M.endpoint = 'pub' -- Nchan publisher endpoint +_M.token = nil +_M.login = nil +_M.password = nil +_M.info = {} + +_M.method = 'POST' + +-- http status codes with info + +_M.codes = { + [200] = 'SUCCESS (channel existed or deleted)', + [201] = 'CREATED (at least 1 subscriber presented)', + [202] = 'ACCEPTED (no subscribers are present)' +} + +function _M.request(message) + local source = ltn12.source.empty() + local endpoint = _M.host..'/'.._M.endpoint + local respbody = {} + local headers = { + ['Content-type'] = 'application/x-www-form-urlencoded', + ['Accept'] = 'text/json' + } + if message then + headers['content-length'] = tostring(#message) + if (type(message) == 'table') then + source = ltn12.source.cat(message) + else + source = ltn12.source.string(message) + end + end + if _M.token then + headers["Authorization"] = 'Bearer '.._M.token + end + if _M.login and _M.password then + headers["Authorization"] = 'Basic '..(mime.b64(_M.login..":".. _M.password)) + end + if _M.port then + endpoint = _M.host..':'.._M.port..'/'.._M.endpoint + end + + local result, respcode, respheaders, respstatus = http.request { + method = _M.method, + headers = headers, + url = endpoint, + source = source, + sink = ltn12.sink.table(respbody) + } + if not _M.codes[respcode] then + return false, 'Request error. Code: '..respcode + end + if respbody then + respbody = table.concat(respbody) + ok,err = pcall(json.decode,respbody) + if not ok then + return false, 'Invalid nchan response' + end + _M.info = json.decode(respbody) + end + return true, _M.codes[respcode] +end + +return _M diff --git a/tests/test.lua b/tests/test.lua new file mode 100755 index 0000000..c521b61 --- /dev/null +++ b/tests/test.lua @@ -0,0 +1,19 @@ +local channel = require('nchan.channel') + +channel.nchan.host = 'http://localhost' +channel.nchan.endpoint = 'pub' + +result,msg = channel.status() +print(result) +print(msg.messages) +print(msg.requested) +print(msg.subscribers) +print(msg.last_message_id) + +result,msg = channel.publish('test') +print(result) +print(channel.nchan.info.messages) +print(channel.nchan.info.requested) +print(channel.nchan.info.subscribers) +print(channel.nchan.info.last_message_id) + diff --git a/tests/tests.sh b/tests/tests.sh new file mode 100644 index 0000000..3e83521 --- /dev/null +++ b/tests/tests.sh @@ -0,0 +1 @@ +curl --request POST --data "test message" -H "Accept: text/json" http://localhost/pub