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 = {}
|
||||
|
||||
module Heimdall
|
||||
VERSION = "0.1 alpha"
|
||||
attr_reader :VERSION
|
||||
|
||||
class ProtocolError < StandardError
|
||||
end
|
||||
|
||||
class UID
|
||||
def initialize
|
||||
@UID_prefix = "abstract" if not @UID_prefix
|
||||
|
@ -22,34 +28,47 @@ module Heimdall
|
|||
@users[user.protoid] = user
|
||||
end
|
||||
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
|
||||
|
||||
class User < UID
|
||||
def initialize(username, protoid)
|
||||
@username = username
|
||||
@protoid = protoid
|
||||
def initialize(data)
|
||||
@username = data["username"]
|
||||
@protoid = data["protocol_id"]
|
||||
@UID_prefix = "user"
|
||||
@direct = DirectChannel.new
|
||||
super()
|
||||
end
|
||||
attr_reader :username
|
||||
attr_reader :protoid
|
||||
end
|
||||
|
||||
class Server < UID
|
||||
def initialize
|
||||
@UID_prefix = "server"
|
||||
super()
|
||||
end
|
||||
attr_reader :direct
|
||||
end
|
||||
|
||||
class Channel < UID
|
||||
def initialize
|
||||
@UID_prefix = "channel"
|
||||
@messages = MsgStack.new
|
||||
@read = 0
|
||||
super()
|
||||
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
|
||||
|
||||
class DirectChannel < Channel
|
||||
|
@ -57,7 +76,6 @@ module Heimdall
|
|||
@UID_prefix = "dchannel"
|
||||
super()
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class ServerChannel < Channel
|
||||
|
@ -68,16 +86,36 @@ module Heimdall
|
|||
end
|
||||
|
||||
class Message < UID
|
||||
def initialize
|
||||
def initialize(data)
|
||||
@content = data["content"]
|
||||
@from = data["from"]
|
||||
@to = data["to"]
|
||||
@UID_prefix = "message"
|
||||
super()
|
||||
end
|
||||
def to_struct
|
||||
return {
|
||||
"content" => @content,
|
||||
"from" => @from,
|
||||
"to" => @to
|
||||
}
|
||||
end
|
||||
attr_reader :content
|
||||
attr_reader :from
|
||||
attr_reader :to
|
||||
end
|
||||
|
||||
class MsgStack < UID
|
||||
def initialize
|
||||
@UID_prefix = "msgstack"
|
||||
@messages = []
|
||||
super()
|
||||
end
|
||||
def push(msg)
|
||||
@messages.append(msg)
|
||||
end
|
||||
def pull(n)
|
||||
@messages.last n
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
153
server.rb
153
server.rb
|
@ -4,41 +4,166 @@ require "json"
|
|||
|
||||
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
|
||||
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"
|
||||
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
|
||||
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|
|
||||
req,res = ctx.request,ctx.response
|
||||
begin
|
||||
data = JSON::Parser.new(req.body).parse
|
||||
require_keys(data,{
|
||||
data = _parse_json(req.body,{
|
||||
username: 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
|
||||
res.body = JSON::fast_generate({
|
||||
error: "#{jsonerror}"
|
||||
})
|
||||
res['Content-Type'] = "application/json"
|
||||
res.status = 400
|
||||
_throw_error(res,jsonerror)
|
||||
rescue KeyError => keyerror
|
||||
res.body = JSON::fast_generate({
|
||||
error: "#{keyerror}"
|
||||
_throw_error(res,keyerror)
|
||||
end
|
||||
end
|
||||
|
||||
post "send" do |ctx|
|
||||
req,res = ctx.request,ctx.response
|
||||
begin
|
||||
data = _parse_json(req.body, {
|
||||
content: String,
|
||||
from: String,
|
||||
to: String
|
||||
})
|
||||
res['Content-Type'] = "application/json"
|
||||
res.status = 400
|
||||
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
|
||||
|
||||
get "version" do |ctx|
|
||||
ctx.response.body = "{\"version\":\"#{Heimdall::VERSION}\"}"
|
||||
ctx.response['Content-Type'] = "application/json"
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
server.start
|
||||
|
|
Loading…
Reference in New Issue