taro/taro-ctl.cr

195 lines
No EOL
4 KiB
Crystal

require "process"
require "io/memory"
require "io"
module Taro
enum WinType
LIST
READER
COMPOSE
end
class Mesg
@type : UInt8
@data : Slice(UInt8)
def type
@type
end
def data
@data
end
def initialize(@type, @data)
end
end
class ChildWindow
@lifetime : Channel(UInt8)
@msg : Channel(Mesg)
@stdout_w : IO::FileDescriptor
@stdout_r : IO::FileDescriptor
@stdin_w : IO::FileDescriptor
@stdin_r : IO::FileDescriptor
@decoding : Bool = false
@szshort : UInt16 = 0
def initialize(w : WinType = WinType::LIST)
@stdout_r, @stdout_w = IO.pipe
@stdin_r, @stdin_w = IO.pipe
@lifetime = Channel(UInt8).new
@msg = Channel(Mesg).new
uxnrom : String = ""
case w
when WinType::LIST then uxnrom = "taro-ls"
when WinType::READER then uxnrom = "taro-reader"
when WinType::COMPOSE then uxnrom = "taro-compose"
end
uxnargs = ["-s", "1", "#{uxnrom}.rom"]
spawn do
Process.run(command: "uxnemu", args: uxnargs, input: @stdin_r, output: @stdout_w, error: Process::Redirect::Inherit)
@lifetime.send(0)
end
spawn do
loop do
@msg.send(read_msg)
end
end
end
def lifetime
@lifetime
end
def msg
@msg
end
def write_msg(msgtype : UInt8, data : Slice)
msgsz = UInt16.new(data.size > 16384 ? 16384 : data.size)
msgtype.to_io(@stdin_w, IO::ByteFormat::BigEndian)
msgsz.to_io(@stdin_w, IO::ByteFormat::BigEndian)
if msgsz == 16384
@stdin_w.write(data[0..msgsz - 2])
10_u8.to_io(@stdin_w, IO::ByteFormat::BigEndian)
else
@stdin_w.write(data[0..msgsz - 1])
end
end
def read_msg
msgType : UInt8 = 0
data : Slice(UInt8) = Slice(UInt8).new(0)
loop do
if @stdout_r.closed?
break
end
if !@decoding
msgType = @stdout_r.read_byte || 0_u8
@decoding = true
elsif @szshort == 0
szslice = Slice(UInt8).new(2)
@stdout_r.read_fully(szslice)
szlow : UInt16 = UInt16.new(szslice[0])*256
szhigh : UInt16 = UInt16.new(szslice[1])
@szshort = szlow + szhigh
else
slc = Slice(UInt8).new(@szshort)
@stdout_r.read_fully(slc)
@decoding = false
data = slc
break
end
end
return Mesg.new(msgType, data)
end
end
class MblazeProxy
@mailbox : String
def initialize
@mailbox = "INBOX"
end
def list_mail(box : String = "INBOX")
mailCmd = "
mbox=${MBOX_ROOT}/#{box}
mdirs ${mbox} | xargs minc > /dev/null
mlist ${mbox} | msort -dr | mseq -S | mscan"
io = IO::Memory.new
Process.run(mailCmd, shell: true, output: io)
return io.to_s
end
def list_mboxes
mailCmd ="for x in $(mdirs ${MBOX_ROOT}); do echo ${x#$MBOX_ROOT/}; done"
io = IO::Memory.new
Process.run(mailCmd, shell: true, output: io)
return io.to_s
end
def set_mbox(box : String)
@mailbox = box
end
end
class TaroCtl
@mblaze : MblazeProxy
@lsWin : ChildWindow
@readWins : Array(ChildWindow)
@composeWins : Array(ChildWindow)
def initialize
@lsWin = ChildWindow.new
@readWins = Array(ChildWindow).new
@composeWins = Array(ChildWindow).new
@mblaze = MblazeProxy.new
list = @mblaze.list_mail
@lsWin.write_msg(2_u8, list.to_slice)
end
def mblaze
@mblaze
end
def mainWindow
@lsWin
end
def readWins
@readWins
end
def composeWins
@composeWins
end
end
end
taro = Taro::TaroCtl.new
loop do
select
when taro.mainWindow.lifetime.receive?
exit
when m = taro.mainWindow.msg.receive
case m.type
when 1 then taro.mblaze.set_mbox(m.data.to_s)
end
end
end