mirror of
https://github.com/Dummi26/mers.git
synced 2025-03-10 14:13:52 +01:00

- updated debug() method to output static_type :: dynamic_type :: value - updated to_string() to output "val" if called on a string (it just uses the fmt methods) - updated format() to only take strings as arguments
206 lines
7.0 KiB
Plaintext
Executable File
206 lines
7.0 KiB
Plaintext
Executable File
lib mers_libs/http_requests
|
|
lib mers_libs/gui
|
|
|
|
// MusicDB is a private project of mine.
|
|
// Basically, a SBC is hooked up to some speakers.
|
|
// It has a database of my songs and can play them.
|
|
// It can be controlled through HTTP requests, such as
|
|
// p- to stop
|
|
// p+ to play
|
|
// qi to get the queue index / playback position
|
|
// l to list all the songs
|
|
// ql or qL to list the queue
|
|
// ...
|
|
// this mers program should work as a very simple gui to remotely control
|
|
// the playback of songs. It should be able to add/remove songs to/from the queue,
|
|
// to start/stop playback, and to display some information about the current song.
|
|
|
|
// the url used to connect to the SBC and use the HTTP api
|
|
api_url = "http:\//192.168.2.103:26315/api/raw?"
|
|
|
|
// start the GUI
|
|
base = gui_init()
|
|
set_title("Mers MusicDB Remote")
|
|
|
|
playback_controls = base.gui_add(Row: [])
|
|
play_button = playback_controls.gui_add(Button: "Play")
|
|
stop_button = playback_controls.gui_add(Button: "Stop")
|
|
|
|
// these functions abstract away the api interactions
|
|
// because they aren't pretty.
|
|
// feel free to skip past this section and look at the gui code instead
|
|
fn make_api_request(to_api string) {
|
|
http_get(api_url.add(to_api))
|
|
}
|
|
fn get_queue_index() {
|
|
r = make_api_request("qi")
|
|
switch! r {
|
|
string {
|
|
r.regex("[0-9]").assume_no_enum().get(0).assume1().parse_int().assume1()
|
|
}
|
|
// return the error
|
|
Err(ErrBuildingRequest(string)/ErrGettingResponseText(string)) r
|
|
}
|
|
}
|
|
fn get_db_contents() {
|
|
// list only 7 = 1 (title) + 2 (artist) + 4 (album)
|
|
r = make_api_request("lo7,")
|
|
switch! r {
|
|
string {
|
|
entries = r.regex("#.*:\n.*\n.*\n.*").assume_no_enum()
|
|
// initialize the list with a default value
|
|
// because mers doesnt know the inner type without it.
|
|
db = [[0 "title" "artist" "album"] ...]
|
|
&db.remove(0)
|
|
for entry entries {
|
|
lines = entry.regex(".*")
|
|
switch! lines {
|
|
[string ...] {
|
|
index_line = &lines.get(0).assume1()
|
|
index = index_line.substring(1 index_line.len().sub(1)).parse_int().assume1()
|
|
title = &lines.get(1).assume1().substring(1)
|
|
artist = &lines.get(2).assume1().substring(1)
|
|
album = &lines.get(3).assume1().substring(1)
|
|
&db.push([index title artist album])
|
|
}
|
|
Err(string) {
|
|
println("invalid response from server; 3u123128731289")
|
|
exit(1)
|
|
}
|
|
}
|
|
}
|
|
db
|
|
}
|
|
Err(ErrBuildingRequest(string)/ErrGettingResponseText(string)) {
|
|
println("couldn't request db from server:")
|
|
print(" ")
|
|
println(r.to_string())
|
|
exit(1)
|
|
}
|
|
}
|
|
}
|
|
fn get_queue() {
|
|
r = make_api_request("ql")
|
|
switch! r {
|
|
string {
|
|
queue = [0 ...]
|
|
&queue.remove(0)
|
|
for index r.regex("[0-9]+[ \n]").assume_no_enum() {
|
|
&queue.push(index.substring(0 index.len().sub(1)).parse_int().assume1())
|
|
}
|
|
queue
|
|
}
|
|
Err(ErrBuildingRequest(string)/ErrGettingResponseText(string)) {
|
|
println("couldn't request queue from server:")
|
|
print(" ")
|
|
println(r.to_string())
|
|
exit(1)
|
|
}
|
|
}
|
|
}
|
|
fn play() {
|
|
r = make_api_request("p+")
|
|
switch! r {
|
|
// success! but nothing to return.
|
|
string []
|
|
// return the error
|
|
Err(ErrBuildingRequest(string)/ErrGettingResponseText(string)) r
|
|
}
|
|
}
|
|
fn stop() {
|
|
r = make_api_request("p-")
|
|
switch! r {
|
|
// success! but nothing to return.
|
|
string []
|
|
// return the error
|
|
Err(ErrBuildingRequest(string)/ErrGettingResponseText(string)) r
|
|
}
|
|
}
|
|
fn queue_song(song_id int) {
|
|
make_api_request("q+{0}".format(song_id.to_string()))
|
|
}
|
|
|
|
// fetch the database contents (a list of songs)
|
|
database = get_db_contents()
|
|
|
|
// this is where all the songs will be displayed.
|
|
songs_gui = base.gui_add(Row: [])
|
|
queue_list = songs_gui.gui_add(Column: [])
|
|
library = songs_gui.gui_add(Column: [])
|
|
|
|
limit = 0 // set to 0 to disable library length limit
|
|
for entry database {
|
|
// <SONG> by <ARTIST> on <ALBUM>
|
|
song = library.gui_add(Row: [])
|
|
song.gui_add(Button: entry.1)
|
|
song.gui_add(Text: "by {0} on {1}".format(entry.2 entry.3))
|
|
limit = limit.sub(1)
|
|
if limit.eq(0) [[]] else []
|
|
}
|
|
|
|
// regularly update the queue
|
|
thread(() {
|
|
queue_index = get_queue_index().assume_no_enum("if the server isn't reachable, it's ok to crash")
|
|
queue_list_inner = queue_list.gui_add(Column: [])
|
|
prev_artist = ""
|
|
prev_album = ""
|
|
for song_id get_queue() {
|
|
this_is_playing = if queue_index.eq(0) { queue_index = -1 true } else if queue_index.gt(0) { queue_index = queue_index.sub(1) false } else { false }
|
|
song = &database.get(song_id).assume1()
|
|
row = queue_list_inner.gui_add(Row: [])
|
|
text = if this_is_playing ">> " else ""
|
|
text = text.add(song.1)
|
|
if prev_artist.eq(song.2) {
|
|
if prev_album.eq(song.3) {
|
|
} else {
|
|
text = text.add("(on {0})".format(song.3))
|
|
}
|
|
} else {
|
|
text = text.add("(by {0} on {1})".format(song.2 song.3))
|
|
}
|
|
row.gui_add(Text: text)
|
|
[]
|
|
}
|
|
sleep(10)
|
|
queue_list_inner.gui_remove()
|
|
})
|
|
|
|
while {
|
|
for event gui_updates() {
|
|
switch! event {
|
|
ButtonPressed([int ...]) {
|
|
e = event.noenum()
|
|
println("Pressed button {0}".format(e.to_string()))
|
|
match e {
|
|
&e.eq(&play_button) {
|
|
println("pressed play.")
|
|
play()
|
|
}
|
|
&e.eq(&stop_button) {
|
|
println("pressed stop.")
|
|
stop()
|
|
}
|
|
{
|
|
// the button is in a row that is in the library,
|
|
// so pop()ing twice gets the library path.
|
|
// THIS WILL BREAK IF THE GUI LIBRARY SWITCHES TO IDs INSTEAD OF PATHS!
|
|
last = &e.pop().assume1()
|
|
slast = &e.pop().assume1()
|
|
matches = &e.eq(&library)
|
|
&e.push(slast)
|
|
&e.push(last)
|
|
if matches e else []
|
|
} {
|
|
// the second to last part of the path is the row within library, which is also the index in the db
|
|
song = &database.get(&e.get(e.len().sub(2)).assume1()).assume1()
|
|
println("Added song \"{0}\" to queue.".format(song.1))
|
|
queue_song(song.0)
|
|
}
|
|
true println("A different button was pressed (unreachable)")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
[]
|
|
}
|