Skip to content

Commit

Permalink
menu roughly works
Browse files Browse the repository at this point in the history
  • Loading branch information
Roger-luo committed Jul 13, 2021
1 parent e302b03 commit a12586e
Show file tree
Hide file tree
Showing 5 changed files with 168 additions and 2 deletions.
2 changes: 2 additions & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ version = "0.1.0"
[deps]
AWS = "fbe9abb3-538b-5e4e-ba9e-bc94f4f92ebc"
Configurations = "5218b696-f38b-4ac9-8b61-a12ec717816d"
Crayons = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f"
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
Expronicon = "6b7a57c9-7cc1-4fdf-b7f5-e857abae3636"
ExproniconLite = "55351af7-c7e9-48d6-89ff-24e801d99491"
GarishPrint = "b0ab02a7-8576-43f7-aa76-eaa7c3897c54"
HTTP = "cd3eb016-35fb-5094-929b-558a96fad6f3"
JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"
UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"

[compat]
Expand Down
7 changes: 6 additions & 1 deletion src/AWSBraket.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ using AWS
using UUIDs
using HTTP
using JSON
using Configurations: from_dict_validate
using AWS: @service

@service STS
Expand All @@ -21,7 +22,7 @@ function parse_device_info(d)
d["deviceCapabilities"] = JSON.parse(d["deviceCapabilities"])
end

return from_dict(Schema.DeviceInfo, d)::Schema.DeviceInfo
return from_dict_validate(Schema.DeviceInfo, d)::Schema.DeviceInfo
end

function get_device(arn::String; aws_config=AWS.global_aws_config())
Expand Down Expand Up @@ -97,4 +98,8 @@ function cancel_quantum_task(client_token::String, task_arn::String)
Braket.cancel_quantum_task(client_token, HTTP.escapeuri(task_arn))
end

using Crayons.Box
using REPL.TerminalMenus
include("menu.jl")

end
129 changes: 129 additions & 0 deletions src/menu.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
mutable struct DeviceMenu <: TerminalMenus.AbstractMenu
options::Vector{Schema.DeviceInfo}
regions::Vector{String}
pagesize::Int
indent::Int
pageoffset::Int
selected::Int
end

function DeviceMenu(; pagesize::Int=5)
all_devices = Schema.DeviceInfo[]
regions = String[]
for region in ["us-east-1", "us-west-1", "us-west-2"]
devices, _ = search_devices(;aws_config = AWSConfig(;region))
append!(all_devices, devices)
append!(regions, fill(region, length(devices)))
end
return DeviceMenu(all_devices, regions; pagesize)
end

function DeviceMenu(
devices::Vector{Schema.DeviceInfo},
regions::Vector{String} = fill(AWS.region(AWS.global_aws_config()), length(devices))
; pagesize::Int=5, warn::Bool=true
)

length(devices) < 1 && error("DeviceMenu must have at least one option")
pagesize < 4 && error("minimum pagesize must be larger than 4")
pagesize = pagesize == -1 ? length(devices) : pagesize
# pagesize shouldn't be bigger than options
pagesize = min(length(devices), pagesize)
# after other checks, pagesize must be greater than 1
pagesize < 1 && error("pagesize must be >= 1")

pageoffset = 0
selected = -1 # none
indent = maximum(x->length(device_name(x)), devices) + 2
return DeviceMenu(devices, regions, pagesize, indent, pageoffset, selected)
end

function device_name(dev::Schema.DeviceInfo)
string(dev.providerName, ":", dev.deviceName)
end

function TerminalMenus.options(m::DeviceMenu)
return m.options
end

TerminalMenus.cancel(m::DeviceMenu) = m.selected = -1

function TerminalMenus.pick(m::DeviceMenu, cursor::Int)
m.selected = cursor
return true #break out of the menu
end

function TerminalMenus.printmenu(out::IO, m::DeviceMenu, cursoridx::Int; oldstate=nothing, init::Bool=false)
buf = IOBuffer()
lastoption = length(m.options)
ncleared = oldstate === nothing ? m.pagesize-1 : oldstate

if init
# like clamp, except this takes the min if max < min
m.pageoffset = max(0, min(cursoridx - m.pagesize ÷ 2, lastoption - m.pagesize))
else
print(buf, "\x1b[999D\x1b[$(ncleared)A") # move left 999 spaces and up `ncleared` lines
end

firstline = m.pageoffset+1
lastline = min(m.pagesize+m.pageoffset, lastoption)
curr_device = m.options[cursoridx]

for i in firstline:lastline
# clearline
print(buf, "\x1b[2K")

upscrollable = i == firstline && m.pageoffset > 0
downscrollable = i == lastline && i != lastoption

if upscrollable && downscrollable
print(buf, TerminalMenus.updown_arrow(m)::Union{Char,String})
elseif upscrollable
print(buf, TerminalMenus.up_arrow(m)::Union{Char,String})
elseif downscrollable
print(buf, TerminalMenus.down_arrow(m)::Union{Char,String})
else
print(buf, ' ')
end

# TODO: use 1.6's implementation when we drop 1.5
# TerminalMenus.printcursor(buf, m, i == cursoridx)
print(buf, i == cursoridx ? '' : ' ', ' ')

name = device_name(m.options[i])
indent = " "^(m.indent - length(name))
device = m.options[cursoridx]::Schema.DeviceInfo

line_idx = i - firstline + 1
print(buf, GREEN_FG(name))

if !isnothing(device.deviceCapabilities) && !isnothing(device.deviceCapabilities.paradigm)
nqubits = device.deviceCapabilities.paradigm.qubitCount
else
nqubits = "unknown"
end

if line_idx == 1
print(buf, indent, LIGHT_BLUE_FG("nqubits: "), GREEN_FG(string(nqubits)))
elseif line_idx == 2
print(buf, indent, LIGHT_BLUE_FG("status: "), GREEN_FG(device.deviceStatus))
elseif line_idx == 3
print(buf, indent, LIGHT_BLUE_FG("region: "), GREEN_FG(m.regions[cursoridx]))
end

(firstline == lastline || i != lastline) && print(buf, "\r\n")
end

newstate = lastline-firstline # final line doesn't have `\n`
if newstate < ncleared && oldstate !== nothing
# we printed fewer lines than last time. Erase the leftovers.
for i = newstate+1:ncleared
print(buf, "\r\n\x1b[2K")
end
print(buf, "\x1b[$(ncleared-newstate)A")
end

print(out, String(take!(buf)))

return newstate
end
2 changes: 1 addition & 1 deletion src/schema/device.jl
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ end
deviceName::String
deviceType::String
deviceStatus::String
deviceCapabilities::DeviceCapabilities
deviceCapabilities::Maybe{DeviceCapabilities} = nothing
end

function Configurations.convert_to_option(::Type{BraketDeviceSchema}, ::Type{VersionNumber}, x)
Expand Down
30 changes: 30 additions & 0 deletions test/menu.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using AWS
using AWSBraket
using REPL.TerminalMenus


devices, _ = AWSBraket.search_devices(;aws_config=AWSConfig(;region="us-east-1"))

menu = AWSBraket.DeviceMenu(devices);

menu = AWSBraket.DeviceMenu()
request("select a device:", menu)



devices, _ = AWSBraket.search_devices(;aws_config=AWSConfig(;region="us-west-2"))

AWS.@service Braket

devices = Braket.search_devices([];aws_config=AWSConfig(;region="us-west-2"))["devices"]

using JSON
using AWSBraket.Schema
using Configurations

from_dict(Schema.DeviceInfo, devices[4])

devices[1]["deviceCapabilities"] = JSON.parse(devices[1]["deviceCapabilities"])

AWSBraket.parse_device_info(devices[4])
devices[4]

0 comments on commit a12586e

Please sign in to comment.