aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeffrey Armstrong <jeff@approximatrix.com>2021-05-07 09:42:16 -0400
committerJeffrey Armstrong <jeff@approximatrix.com>2021-05-07 09:42:16 -0400
commit0f31824a5e4969d56d88678e05274163be3d8b77 (patch)
tree1d2a7b5f84d1413166509fb677f3d770b2d646ef
parente7848c2d61bb8fb13b4620ba0c8eaf20a1965ffa (diff)
downloadlevitating-0f31824a5e4969d56d88678e05274163be3d8b77.tar.gz
levitating-0f31824a5e4969d56d88678e05274163be3d8b77.zip
Instructions and players now displayed via the CGI interface. Added 'page' member to the request derived type.
-rw-r--r--captain/requtils.f9016
-rw-r--r--captain/response.f9016
-rw-r--r--captain/web.f90231
3 files changed, 254 insertions, 9 deletions
diff --git a/captain/requtils.f90 b/captain/requtils.f90
index b28500e..7010bcb 100644
--- a/captain/requtils.f90
+++ b/captain/requtils.f90
@@ -186,13 +186,14 @@ contains
end function request_static
- function render_jobs_links(jobs, startindex, stopindex, gemini_mode) result(res)
+ function render_jobs_links(jobs, startindex, stopindex, gemini_mode, link_prefix) result(res)
use captain_db
implicit none
type(job), dimension(:), pointer, intent(in)::jobs
integer, intent(in), optional::startindex, stopindex
logical, intent(in)::gemini_mode
+ character(*), intent(in), optional::link_prefix
character(len=:), pointer::res
integer::nsize, i, first, last
@@ -200,6 +201,13 @@ contains
character(len=(2*PLAYER_NAME_LENGTH + 64))::link
character(PLAYER_NAME_LENGTH)::player, instruction
character(1)::nl = new_line(' ')
+ character(64)::int_link_prefix
+
+ if(present(link_prefix)) then
+ int_link_prefix = link_prefix
+ else
+ int_link_prefix = " "
+ end if
if(.not. associated(jobs)) then
allocate(character(len=32)::res)
@@ -233,7 +241,8 @@ contains
write(int_text, '(I8)') jobs(i)%id
if(gemini_mode) then
- link = "=> jobs/"//trim(adjustl(int_text))//".gmi "// &
+ link = "=> "//trim(int_link_prefix)//"jobs/"// &
+ trim(adjustl(int_text))//".gmi "// &
trim(get_status_utf8(jobs(i)%status))//" Job "// &
trim(adjustl(int_text))//" - "//trim(instruction)
@@ -241,7 +250,8 @@ contains
else
res = trim(res)//nl//' <li><div class="job_result_listitem">'
- link = ' <p><strong><a href="jobs/'//trim(adjustl(int_text))//'.html" >'// &
+ link = ' <p><strong><a href="'//trim(int_link_prefix)//'jobs/'// &
+ trim(adjustl(int_text))//'.html" >'// &
trim(get_status_utf8(jobs(i)%status))//" Job "// &
trim(adjustl(int_text))//" - "//trim(instruction)// &
'</a></strong></p>'
diff --git a/captain/response.f90 b/captain/response.f90
index a4fe24e..610b070 100644
--- a/captain/response.f90
+++ b/captain/response.f90
@@ -61,6 +61,7 @@ implicit none
character(len=:), pointer::server => null()
character(len=:), pointer::protocol => null()
character(len=:), pointer::location => null()
+ character(len=:), pointer::page => null()
character(len=:), pointer::query_string => null()
contains
@@ -101,6 +102,7 @@ contains
character(*), intent(in)::str
character(*), intent(in), optional::server_explicit, protocol_explicit
+ character(len=:), allocatable::temppage
integer::i, j, n
n = len_trim(str)
@@ -168,6 +170,16 @@ contains
call write_log("Location: "//self%location, LOG_DEBUG)
end if
+ ! and page, which is really just a last location if there is an extension...
+ ! I realize this is not so great, but whatever.
+ allocate(character(len=len(self%location)) :: temppage)
+ call self%last_component(temppage)
+ if(index(temppage, ".") > 0) then
+ allocate(character(len=len_trim(temppage)) :: self%page)
+ self%page = temppage
+ end if
+ deallocate(temppage)
+
end subroutine request_init
function request_component_start_location(self, i_component) result(res)
@@ -341,6 +353,10 @@ contains
deallocate(self%protocol)
end if
+ if(associated(self%page)) then
+ deallocate(self%page)
+ end if
+
end subroutine request_destroy
subroutine response_destroy(resp)
diff --git a/captain/web.f90 b/captain/web.f90
index 423f7ed..55f12a0 100644
--- a/captain/web.f90
+++ b/captain/web.f90
@@ -64,6 +64,225 @@ contains
end function html_link
+ function generate_one_instuction_html(req) result(res)
+ use captain_db
+ use server_response
+ use request_utils, only: get_status_utf8, render_jobs_links
+ implicit none
+
+ type(request)::req
+ character(len=:), pointer::res
+ integer::id_from_req
+
+ character(128)::instruction_name
+ type(job), dimension(:), pointer::jobs
+ integer, dimension(:), pointer::players
+ character(len=PLAYER_NAME_LENGTH), dimension(:), pointer::all_players
+ integer::i, j, n_jobs, n_players, nsize
+
+ character(len=:), pointer::job_link_text, one_link
+ character(1)::nl = new_line(' ')
+ character(PLAYER_NAME_LENGTH)::player_name
+ character(4)::player_status
+
+ i = index(req%page, ".html")
+ instruction_name = req%page(1:i-1)
+ id_from_req = get_instruction_id(trim(instruction_name))
+
+ jobs => get_jobs_for_instruction(id_from_req)
+
+ if(associated(jobs)) then
+ n_jobs = size(jobs)
+ job_link_text => render_jobs_links(jobs, gemini_mode=.false., link_prefix="../")
+ else
+ n_jobs = 0
+ job_link_text => null()
+ end if
+
+ players => get_instruction_players(id_from_req)
+ if(associated(players)) then
+ n_players = size(players)
+ else
+ n_players = 0
+ end if
+
+ nsize = 1024
+ if(n_jobs > 0) then
+ nsize = nsize + len_trim(job_link_text)
+ end if
+ if(n_players > 0) then
+ nsize = nsize + n_players*(2*PLAYER_NAME_LENGTH+64)
+ end if
+
+ nsize = nsize + get_player_count()*(2*PLAYER_NAME_LENGTH+64)
+
+ allocate(character(len=nsize) :: res)
+
+ res = "<h2>"//trim(instruction_name)//"</h2>"
+
+ one_link => html_link(trim(instruction_name)//".json", &
+ "View Raw")
+ res = trim(res)//nl//"<p><em>"//one_link//"</em></p>"
+ deallocate(one_link)
+
+ if(n_players == 0) then
+ res = trim(res)//nl//"<p>No players currently can run these instructions</p>"
+ else
+ res = trim(res)//nl//"<h3>Launch Now</h3>"//nl//"<ul>"
+
+ do i = 1, n_players
+ call get_player_name(players(i), player_name)
+ if(is_player_busy(players(i))) then
+ player_status = get_status_utf8(PLAYER_STATUS_BUSY)
+ else
+ player_status = get_status_utf8(PLAYER_STATUS_IDLE)
+ end if
+
+ one_link => html_link(req%page//"?launch="//trim(player_name), &
+ trim(player_status)//" "//trim(player_name))
+
+ res = trim(res)//nl//"<li>"//trim(one_link)//"</li>"
+
+ end do
+
+ res = trim(res)//nl//"</ul>"
+ end if
+
+ res = trim(res)//nl//"<h3>Jobs</h3>"
+ if(n_jobs == 0) then
+ res = trim(res)//nl//"None Yet"
+ else
+ res = trim(res)//nl//job_link_text
+ deallocate(job_link_text)
+ end if
+
+ all_players => get_player_names()
+ if(associated(all_players)) then
+ res = trim(res)//nl//"<h3>Assign</h3>"//nl//"<p>Assign a player to these instructions</p>"//nl//"<ul>"
+ do i = 1, size(all_players)
+ if(n_players > 0) then
+ j = get_player_id(all_players(i))
+ if(any(j == players)) then
+ cycle
+ end if
+ end if
+
+ one_link => html_link(req%page//"?assign="//trim(all_players(i)), &
+ trim(all_players(i)))
+
+ res = trim(res)//nl//"<li>"//one_link//"</li>"
+ deallocate(one_link)
+ end do
+ res = trim(res)//nl//"</ul>"
+ deallocate(all_players)
+ end if
+
+ if(n_players > 0) then
+ res = trim(res)//nl//"<h3>Remove</h3>"//nl//"<p>Remove a player from these instructions</p>"//nl//"<ul>"
+ do i = 1, n_players
+ call get_player_name(players(i), player_name)
+
+ one_link => html_link(req%page//"?remove="//trim(player_name), &
+ trim(player_name))
+
+ res = trim(res)//nl//"<li>"//one_link//"</li>"
+ deallocate(one_link)
+ end do
+ res = trim(res)//nl//"</ul>"
+ end if
+
+ end function generate_one_instuction_html
+
+ function generate_instructions_html() result(res)
+ use captain_db
+ implicit none
+
+ character(len=:), pointer::res
+ character(len=PLAYER_NAME_LENGTH), dimension(:), pointer::instruction_names
+ integer::n, i, nsize
+
+ character(len=:), pointer::one_player
+
+ n = get_instuctions_count()
+
+ if(n == 0) then
+
+ allocate(character(len=1024) :: res)
+ res = "None Yet"
+
+ else
+
+ instruction_names => get_instruction_names()
+ nsize = 1024
+ do i = 1, size(instruction_names)
+ nsize = nsize + 16 + 2*len_trim(instruction_names(i))
+ end do
+
+ allocate(character(len=nsize) :: res)
+ res = "<h2>Instructions</h2>"//new_line(' ')//"<ul>"
+
+ do i = 1, n
+ one_player => html_link("instructions/"//trim(instruction_names(i))//".html", &
+ trim(instruction_names(i)))
+ res = trim(res)//new_line(' ')//"<li>"//trim(one_player)//"</li>"
+ end do
+
+ res = trim(res)//new_line(' ')//"</ul>"
+
+ deallocate(instruction_names)
+
+ end if
+
+ res = trim(res)//new_line(' ')//"<h2>Management</h2>"// &
+ new_line(' ')//"coming soon (Scan for Instructions)"
+
+ end function generate_instructions_html
+
+ function generate_players_html() result(res)
+ use captain_db
+ implicit none
+
+ character(len=:), pointer::res
+ character(len=PLAYER_NAME_LENGTH), dimension(:), pointer::players
+ integer::n, i, nsize
+
+ character(len=:), pointer::one_player
+
+ n = get_player_count()
+ if(n == 0) then
+
+ allocate(character(len=1024) :: res)
+
+ res = "None Yet"
+
+ else
+
+ players => get_player_names()
+
+ nsize = 1024
+ do i = 1, size(players)
+ nsize = nsize + 16 + 2*len_trim(players(i))
+ end do
+
+ allocate(character(len=nsize) :: res)
+ res = "<h2>Existing Players</h2>"//new_line(' ')//"<ul>"
+
+ do i = 1, n
+ one_player => html_link("players/"//trim(players(i))//".html", &
+ trim(players(i)))
+ res = trim(res)//new_line(' ')//"<li>"//trim(one_player)//"</li>"
+ deallocate(one_player)
+ end do
+
+ res = trim(res)//new_line(' ')//"</ul>"
+ deallocate(players)
+ end if
+
+ res = trim(res)//new_line(' ')//"<h2>Management</h2>"// &
+ new_line(' ')//"<p>coming soon (add player)</p>"
+
+ end function generate_players_html
+
function generate_one_job_html(req) result(res)
use captain_db
use server_response
@@ -356,8 +575,8 @@ contains
else if(trim(req%location) == "/players.html") then
call page%assign('title', 'Players')
- !contents => generate_players_gemini()
- !call page%assign('contents', contents)
+ contents => generate_players_html()
+ call page%assign('contents', contents)
else if(req%location(1:9) == '/players/') then
@@ -368,14 +587,14 @@ contains
else if(trim(req%location) == "/instructions.html") then
call page%assign('title', 'Build Instructions')
- !contents => generate_instructions_gemini()
- !call page%assign('contents', contents)
+ contents => generate_instructions_html()
+ call page%assign('contents', contents)
else if(trim(first) == "instructions") then
call page%assign('title', 'Build Instructions')
- !contents => generate_one_instuction_gemini(req)
- !call page%assign('contents', contents)
+ contents => generate_one_instuction_html(req)
+ call page%assign('contents', contents)
else if(trim(first) == "jobs") then