basic messaging works
This commit is contained in:
parent
edc15522cd
commit
6a73d58574
|
@ -0,0 +1,77 @@
|
||||||
|
#!/usr/bin/ruby
|
||||||
|
require 'readline'
|
||||||
|
require 'net/http'
|
||||||
|
require 'json'
|
||||||
|
require 'uri'
|
||||||
|
puts "Connecting to server #{ARGV[0]} on port #{ARGV[1]}"
|
||||||
|
def get(path)
|
||||||
|
where = URI("http://#{ARGV[0]}:#{ARGV[1]}/#{path}")
|
||||||
|
JSON.parse(Net::HTTP.get(where))
|
||||||
|
end
|
||||||
|
|
||||||
|
def post(path,data)
|
||||||
|
where = URI("http://#{ARGV[0]}:#{ARGV[1]}/#{path}")
|
||||||
|
Net::HTTP.post(where,data.to_json)
|
||||||
|
end
|
||||||
|
|
||||||
|
version = get("version")["version"]
|
||||||
|
puts "Server reported version: #{version}"
|
||||||
|
print "Nickname> "
|
||||||
|
nickname = $stdin.gets.strip
|
||||||
|
puts "Trying to log in..."
|
||||||
|
res = get("/user/exists?protocol_id=#{"heimdall-"+nickname}")
|
||||||
|
puts "Account exists! exiting" if res["exists"]
|
||||||
|
return if res["exists"]
|
||||||
|
puts "Creating account..."
|
||||||
|
test = post("/user/new",{username: nickname, protocol_id: "heimdall-"+nickname})
|
||||||
|
unless test.kind_of? Net::HTTPOK then
|
||||||
|
puts "Something went wrong! exiting"
|
||||||
|
exit
|
||||||
|
end
|
||||||
|
puts "Your id is: heimdall-#{nickname}"
|
||||||
|
Thread.new do
|
||||||
|
while true do
|
||||||
|
sleep 1
|
||||||
|
messages = get("/user/read?protocol_id=#{"heimdall-"+nickname}")
|
||||||
|
if messages["error"] then
|
||||||
|
puts "Error: #{messages["error"]}"
|
||||||
|
next
|
||||||
|
end
|
||||||
|
messages["messages"].each { |x|
|
||||||
|
puts "#{x["from"]} says: #{x["content"]}"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
target = nil
|
||||||
|
|
||||||
|
at_exit do
|
||||||
|
post("/user/delete",{
|
||||||
|
"protocol_id"=> "heimdall-"+nickname
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
while buf = Readline.readline("> ", true)
|
||||||
|
if buf == "/help" then
|
||||||
|
puts "Commands:"
|
||||||
|
puts "/help - this message"
|
||||||
|
puts "/send <protcol_id> - direct messages to somebody"
|
||||||
|
puts "/exit - quit program"
|
||||||
|
end
|
||||||
|
if buf == "/exit" then
|
||||||
|
post("/user/delete",{
|
||||||
|
"protocol_id"=> "heimdall-"+nickname
|
||||||
|
})
|
||||||
|
exit
|
||||||
|
end
|
||||||
|
if target then
|
||||||
|
post("/user/send", {
|
||||||
|
"to" => target,
|
||||||
|
"content" => buf,
|
||||||
|
"from" => "heimdall-"+nickname
|
||||||
|
})
|
||||||
|
end
|
||||||
|
if buf.match(/^\/send .*$/) then
|
||||||
|
target = buf.match(/^\/send ([^\s]*)$/)[1]
|
||||||
|
end
|
||||||
|
end
|
66
proto.rb
66
proto.rb
|
@ -1,6 +1,12 @@
|
||||||
UIDS = {}
|
UIDS = {}
|
||||||
|
|
||||||
module Heimdall
|
module Heimdall
|
||||||
|
VERSION = "0.1 alpha"
|
||||||
|
attr_reader :VERSION
|
||||||
|
|
||||||
|
class ProtocolError < StandardError
|
||||||
|
end
|
||||||
|
|
||||||
class UID
|
class UID
|
||||||
def initialize
|
def initialize
|
||||||
@UID_prefix = "abstract" if not @UID_prefix
|
@UID_prefix = "abstract" if not @UID_prefix
|
||||||
|
@ -22,34 +28,47 @@ module Heimdall
|
||||||
@users[user.protoid] = user
|
@users[user.protoid] = user
|
||||||
end
|
end
|
||||||
def get(protoid)
|
def get(protoid)
|
||||||
return @users[user.protoid]
|
raise ProtocolError, "user not found" if not @users[protoid]
|
||||||
|
return @users[protoid]
|
||||||
|
end
|
||||||
|
def delete(protoid)
|
||||||
|
@users.delete protoid
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class User < UID
|
class User < UID
|
||||||
def initialize(username, protoid)
|
def initialize(data)
|
||||||
@username = username
|
@username = data["username"]
|
||||||
@protoid = protoid
|
@protoid = data["protocol_id"]
|
||||||
@UID_prefix = "user"
|
@UID_prefix = "user"
|
||||||
|
@direct = DirectChannel.new
|
||||||
super()
|
super()
|
||||||
end
|
end
|
||||||
attr_reader :username
|
attr_reader :username
|
||||||
attr_reader :protoid
|
attr_reader :protoid
|
||||||
end
|
attr_reader :direct
|
||||||
|
|
||||||
class Server < UID
|
|
||||||
def initialize
|
|
||||||
@UID_prefix = "server"
|
|
||||||
super()
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
class Channel < UID
|
class Channel < UID
|
||||||
def initialize
|
def initialize
|
||||||
@UID_prefix = "channel"
|
@UID_prefix = "channel"
|
||||||
|
@messages = MsgStack.new
|
||||||
|
@read = 0
|
||||||
super()
|
super()
|
||||||
end
|
end
|
||||||
|
def send(msg)
|
||||||
|
@messages.push(msg)
|
||||||
|
@read = @read+1
|
||||||
|
end
|
||||||
|
def get(n = 1)
|
||||||
|
raise Heimdall::ProtocolError, "Invalid number of messages" if n < 0
|
||||||
|
return @messages.pull(n)
|
||||||
|
end
|
||||||
|
def read()
|
||||||
|
messages = @messages.pull(@read)
|
||||||
|
@read = 0
|
||||||
|
return messages
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class DirectChannel < Channel
|
class DirectChannel < Channel
|
||||||
|
@ -57,7 +76,6 @@ module Heimdall
|
||||||
@UID_prefix = "dchannel"
|
@UID_prefix = "dchannel"
|
||||||
super()
|
super()
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
class ServerChannel < Channel
|
class ServerChannel < Channel
|
||||||
|
@ -68,16 +86,36 @@ module Heimdall
|
||||||
end
|
end
|
||||||
|
|
||||||
class Message < UID
|
class Message < UID
|
||||||
def initialize
|
def initialize(data)
|
||||||
|
@content = data["content"]
|
||||||
|
@from = data["from"]
|
||||||
|
@to = data["to"]
|
||||||
@UID_prefix = "message"
|
@UID_prefix = "message"
|
||||||
super()
|
super()
|
||||||
end
|
end
|
||||||
|
def to_struct
|
||||||
|
return {
|
||||||
|
"content" => @content,
|
||||||
|
"from" => @from,
|
||||||
|
"to" => @to
|
||||||
|
}
|
||||||
|
end
|
||||||
|
attr_reader :content
|
||||||
|
attr_reader :from
|
||||||
|
attr_reader :to
|
||||||
end
|
end
|
||||||
|
|
||||||
class MsgStack < UID
|
class MsgStack < UID
|
||||||
def initialize
|
def initialize
|
||||||
@UID_prefix = "msgstack"
|
@UID_prefix = "msgstack"
|
||||||
|
@messages = []
|
||||||
super()
|
super()
|
||||||
end
|
end
|
||||||
|
def push(msg)
|
||||||
|
@messages.append(msg)
|
||||||
|
end
|
||||||
|
def pull(n)
|
||||||
|
@messages.last n
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
155
server.rb
155
server.rb
|
@ -4,41 +4,166 @@ require "json"
|
||||||
|
|
||||||
Users = Heimdall::UserCache.new
|
Users = Heimdall::UserCache.new
|
||||||
|
|
||||||
def require_keys(dict,key_dict)
|
def _require_keys(dict,key_dict)
|
||||||
raise KeyError, "not a dict" unless dict.kind_of? Hash
|
raise KeyError, "not a dict" unless dict.kind_of? Hash
|
||||||
key_dict.each_pair { |k,v|
|
key_dict.each_pair { |k,v|
|
||||||
unless (dict.has_key? k) and (dict[k].kind_of? v) then
|
unless (dict.has_key? k.to_s) and (dict[k.to_s].kind_of? v) then
|
||||||
raise KeyError, "key #{k} of type #{v} required"
|
raise KeyError, "key #{k} of type #{v} required"
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def _send_json(res,data,code: 200)
|
||||||
|
res.body = JSON::fast_generate(data)
|
||||||
|
res['Content-Type'] = "application/json"
|
||||||
|
res.status = code
|
||||||
|
end
|
||||||
|
|
||||||
|
def _throw_error(res,error)
|
||||||
|
_send_json(res,{
|
||||||
|
error: "#{error}"
|
||||||
|
},code: 400)
|
||||||
|
end
|
||||||
|
|
||||||
|
def _parse_json(body,key_dict)
|
||||||
|
data = JSON::Parser.new(body).parse
|
||||||
|
_require_keys(data,key_dict)
|
||||||
|
return data
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
server = Hyde::Server.new Port: 8000 do
|
server = Hyde::Server.new Port: 8000 do
|
||||||
path "user" do
|
path "user" do
|
||||||
|
preprocess do |ctx|
|
||||||
|
puts ctx.request.query.inspect
|
||||||
|
puts ctx.request.body.inspect
|
||||||
|
end
|
||||||
|
|
||||||
|
get "exists" do |ctx|
|
||||||
|
req,res = ctx.request,ctx.response
|
||||||
|
begin
|
||||||
|
_require_keys(req.query, {
|
||||||
|
protocol_id: String
|
||||||
|
})
|
||||||
|
_send_json(res,{
|
||||||
|
exists: (Users.get(req.query["protocol_id"]) != nil)
|
||||||
|
})
|
||||||
|
rescue KeyError => keyerror
|
||||||
|
_throw_error(res,keyerror)
|
||||||
|
rescue Heimdall::ProtocolError => protoerr
|
||||||
|
_send_json(res, {
|
||||||
|
exists: false
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
post "new" do |ctx|
|
post "new" do |ctx|
|
||||||
req,res = ctx.request,ctx.response
|
req,res = ctx.request,ctx.response
|
||||||
begin
|
begin
|
||||||
data = JSON::Parser.new(req.body).parse
|
data = _parse_json(req.body,{
|
||||||
require_keys(data,{
|
|
||||||
username: String,
|
username: String,
|
||||||
protocol_id: String
|
protocol_id: String
|
||||||
})
|
})
|
||||||
Users.add(Heimdall::User.new data[:username], data[:protocol_id])
|
new_user = Heimdall::User.new(data)
|
||||||
|
Users.add(new_user)
|
||||||
|
_send_json(res,{
|
||||||
|
uid: new_user.UID
|
||||||
|
})
|
||||||
rescue JSON::ParserError => jsonerror
|
rescue JSON::ParserError => jsonerror
|
||||||
res.body = JSON::fast_generate({
|
_throw_error(res,jsonerror)
|
||||||
error: "#{jsonerror}"
|
|
||||||
})
|
|
||||||
res['Content-Type'] = "application/json"
|
|
||||||
res.status = 400
|
|
||||||
rescue KeyError => keyerror
|
rescue KeyError => keyerror
|
||||||
res.body = JSON::fast_generate({
|
_throw_error(res,keyerror)
|
||||||
error: "#{keyerror}"
|
|
||||||
})
|
|
||||||
res['Content-Type'] = "application/json"
|
|
||||||
res.status = 400
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
post "send" do |ctx|
|
||||||
|
req,res = ctx.request,ctx.response
|
||||||
|
begin
|
||||||
|
data = _parse_json(req.body, {
|
||||||
|
content: String,
|
||||||
|
from: String,
|
||||||
|
to: String
|
||||||
|
})
|
||||||
|
new_message = Heimdall::Message.new(data)
|
||||||
|
Users.get(new_message.to).direct.send(new_message)
|
||||||
|
_send_json(res,{
|
||||||
|
uid: new_message.UID
|
||||||
|
})
|
||||||
|
rescue JSON::ParserError => jsonerror
|
||||||
|
_throw_error(res,jsonerror)
|
||||||
|
rescue KeyError => keyerror
|
||||||
|
_throw_error(res,keyerror)
|
||||||
|
rescue Heimdall::ProtocolError => protoerr
|
||||||
|
_throw_error(res,protoerr)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
get "get" do |ctx|
|
||||||
|
req,res = ctx.request,ctx.response
|
||||||
|
begin
|
||||||
|
_require_keys(req.query,{
|
||||||
|
n: Integer,
|
||||||
|
protocol_id: String
|
||||||
|
})
|
||||||
|
number = req.query[:n]
|
||||||
|
id = req.query["protocol_id"]
|
||||||
|
user = Users.get(id)
|
||||||
|
messages = user.direct.get(number)
|
||||||
|
_send_json(res, {
|
||||||
|
messages: messages.map { |x|
|
||||||
|
x = x.to_struct
|
||||||
|
x["username"] = Users.get(x["from"]).username
|
||||||
|
x
|
||||||
|
}
|
||||||
|
})
|
||||||
|
rescue Heimdall::ProtocolError => protoerr
|
||||||
|
_throw_error(res,protoerr)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
get "read" do |ctx|
|
||||||
|
req,res = ctx.request,ctx.response
|
||||||
|
begin
|
||||||
|
_require_keys(req.query,{
|
||||||
|
protocol_id: String
|
||||||
|
})
|
||||||
|
id = req.query["protocol_id"]
|
||||||
|
user = Users.get(id)
|
||||||
|
messages = user.direct.read
|
||||||
|
_send_json(res, {
|
||||||
|
messages: messages.map { |x|
|
||||||
|
x = x.to_struct
|
||||||
|
x["username"] = Users.get(x["from"]).username
|
||||||
|
x
|
||||||
|
}
|
||||||
|
})
|
||||||
|
rescue Heimdall::ProtocolError => protoerr
|
||||||
|
_throw_error(res,protoerr)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
post "delete" do |ctx|
|
||||||
|
req,res = ctx.request, ctx.response
|
||||||
|
begin
|
||||||
|
data = _parse_json(req.body,{
|
||||||
|
protocol_id: String
|
||||||
|
})
|
||||||
|
id = data["protocol_id"]
|
||||||
|
_send_json(res, {
|
||||||
|
uid: Users.get(id).UID
|
||||||
|
})
|
||||||
|
Users.delete(id)
|
||||||
|
rescue Heimdall::ProtocolError => protoerr
|
||||||
|
_throw_error(res,protoerr)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
get "version" do |ctx|
|
||||||
|
ctx.response.body = "{\"version\":\"#{Heimdall::VERSION}\"}"
|
||||||
|
ctx.response['Content-Type'] = "application/json"
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
server.start
|
server.start
|
||||||
|
|
Loading…
Reference in New Issue