Packages
nerves
1.7.9
1.15.0
1.14.3
1.14.2
1.14.1
1.14.0
1.13.2
1.13.1
1.13.0
1.12.0
1.11.3
1.11.2
1.11.1
1.11.0
1.10.5
1.10.4
1.10.3
1.10.2
1.10.1
1.10.0
1.9.3
1.9.2
retired
1.9.1
1.9.0
1.8.0
1.7.17
1.7.16
1.7.15
1.7.14
retired
1.7.13
1.7.12
1.7.11
1.7.10
1.7.9
1.7.8
1.7.7
1.7.6
1.7.5
1.7.4
1.7.3
1.7.2
retired
1.7.1
retired
1.7.0
retired
1.6.7
1.6.6
1.6.5
1.6.4
1.6.3
1.6.2
1.6.1
1.6.0
1.5.5
1.5.4
1.5.3
1.5.2
1.5.1
1.5.0
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.4
1.3.3
1.3.2
1.3.1
1.3.0
1.2.1
1.2.0
1.1.1
1.1.0
1.0.1
1.0.0
1.0.0-rc.2
1.0.0-rc.1
1.0.0-rc.0
0.11.0
0.10.1
0.10.0
0.9.4
0.9.3
0.9.2
0.9.1
0.9.0
0.8.3
0.8.2
0.8.1
0.8.0
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.1
0.6.0
0.5.2
0.5.1
0.5.0
0.4.8
0.4.7
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.4.0-rc.0
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.2.0
Craft and deploy bulletproof embedded software
Current section
Files
Jump to
Current section
Files
lib/nerves/utils/stream.ex
defmodule Nerves.Utils.Stream do
use GenServer
@timer 10_000
def start_link(opts) do
GenServer.start_link(__MODULE__, opts)
end
def stop(pid) do
GenServer.stop(pid)
end
def history(pid) do
GenServer.call(pid, :history)
end
def init(opts) do
file = opts[:file]
history_lines = opts[:history_lines] || 100
if file != nil do
File.write(file, "", [:write])
end
{:ok,
%{
file: opts[:file],
timer: Process.send_after(self(), :keep_alive, @timer),
history: :queue.new(),
history_lines: history_lines,
history_saved: 0
}}
end
def handle_call(:history, _from, s) do
history =
s.history
|> :queue.to_list()
|> Enum.join()
{:reply, history, s}
end
def handle_info({:io_request, from, reply_as, {:put_chars, _encoding, chars}} = data, s) do
if s.file != nil do
File.write(s.file, chars, [:append])
end
s = save_history(s, chars)
reply(from, reply_as, :ok)
{:noreply, stdout(chars, data, s)}
end
def handle_info(:keep_alive, s) do
IO.write(".")
{:noreply, reset_timer(s)}
end
def stdout(<<">>>", tail::binary>>, _message, s), do: trim_write(">>>", "\n", tail, s)
def stdout(<<"\e[7m>>>", tail::binary>>, _message, s), do: trim_write(">>>", "\e[7m", tail, s)
def stdout(_, _, s), do: s
defp trim_write(trim, split, bin, s) do
IO.write("\n")
[bin | _] =
bin
|> String.split(trim)
(trim <> bin)
|> String.split(split)
|> List.first()
|> String.trim()
|> IO.write()
reset_timer(s)
end
defp reset_timer(s) do
Process.cancel_timer(s.timer)
%{s | timer: Process.send_after(self(), :keep_alive, @timer)}
end
defp save_history(%{history_saved: lines, history_lines: lines} = s, line) do
history = :queue.in(line, s.history)
{_, history} = :queue.out(history)
%{s | history: history}
end
defp save_history(s, line) do
history = :queue.in(line, s.history)
%{s | history: history, history_saved: s.history_saved + 1}
end
def reply(from, reply_as, reply) do
send(from, {:io_reply, reply_as, reply})
end
end