aboutsummaryrefslogtreecommitdiff
path: root/captain/external.f90
diff options
context:
space:
mode:
authorJeffrey Armstrong <jeff@approximatrix.com>2021-04-13 09:56:28 -0400
committerJeffrey Armstrong <jeff@approximatrix.com>2021-04-13 09:56:28 -0400
commit14441b7f0d6dd0a101b38a4500fe1f662ae00215 (patch)
tree32a950d3f5817335dda2783eaad5609dd6268d98 /captain/external.f90
parenta001a16dbb64590172677092e2a55b594c6a2f7b (diff)
downloadlevitating-14441b7f0d6dd0a101b38a4500fe1f662ae00215.tar.gz
levitating-14441b7f0d6dd0a101b38a4500fe1f662ae00215.zip
Releases page and file/dir listing works great on Linux. Should work on BSD hosts as well.
Diffstat (limited to 'captain/external.f90')
-rw-r--r--captain/external.f9092
1 files changed, 90 insertions, 2 deletions
diff --git a/captain/external.f90 b/captain/external.f90
index c4dcb5a..3ffa819 100644
--- a/captain/external.f90
+++ b/captain/external.f90
@@ -248,6 +248,92 @@ contains
end subroutine get_job_page_title
+ function generate_releases_gemini(req) result(res)
+ use utilities
+ use server_response
+ use config
+ implicit none
+
+ type(request), intent(in)::req
+ character(len=:), pointer::res
+ character(len=DIR_LIST_STRING_LENGTH), dimension(:), pointer::directories
+ character(len=DIR_LIST_STRING_LENGTH), dimension(:), pointer::files
+
+ character(1024)::public_path, local_path, subpath
+ integer::allocation_size, i
+ character(1)::nl = new_line(' ')
+ character(4)::folder_icon = char(240)//char(159)//char(147)//char(129)
+
+ if(.not. associated(req%query_string)) then
+ public_path = "/releases"
+ local_path = release_dir
+ else
+ call combine_paths("/releases", req%query_string, public_path)
+ call combine_paths(release_dir, req%query_string, local_path)
+ end if
+
+ res => null()
+
+ ! Easy safety check - no relative paths
+ if(index(local_path, '..') > 0) then
+ allocate(character(len=64)::res)
+ res = "None Found"
+ return
+ end if
+
+ directories => get_directories_in_directory(local_path)
+ files => get_files_in_directory(local_path)
+
+ allocation_size = 1024
+ if(associated(directories)) then
+ allocation_size = allocation_size + size(directories) * DIR_LIST_STRING_LENGTH
+ end if
+ if(associated(files)) then
+ allocation_size = allocation_size + size(files) * DIR_LIST_STRING_LENGTH
+ end if
+ allocate(character(len=allocation_size) :: res)
+ res = "## Listing for "//trim(public_path)
+
+ ! Add an "Up" link
+ if(trim(public_path) /= "/releases") then
+ i = index(req%query_string, "/", back=.true.)
+ if(i > 0) then
+ res = trim(res)//nl//"=> /releases.gmi?"//req%query_string(1:(i-1))//" Up a directory"
+ else
+ res = trim(res)//nl//"=> /releases.gmi Up a directory"
+ end if
+ end if
+
+ if(associated(directories)) then
+
+ do i = 1, size(directories)
+
+ if(associated(req%query_string)) then
+ call combine_paths(req%query_string, trim(directories(i)), subpath)
+ else
+ subpath = trim(directories(i))
+ end if
+
+ res = trim(res)//nl//"=> /releases.gmi?"//trim(subpath)//" "//folder_icon//" "//trim(directories(i))
+ end do
+
+ deallocate(directories)
+
+ end if
+
+ if(associated(files)) then
+
+ do i = 1, size(files)
+ call combine_paths(public_path, trim(files(i)), subpath)
+ res = trim(res)//nl//"=> "//trim(subpath)//" "//trim(files(i))
+ end do
+
+ deallocate(files)
+
+ end if
+
+ end function generate_releases_gemini
+
function generate_players_gemini() result(res)
use captain_db
implicit none
@@ -544,8 +630,8 @@ contains
resp%code = GEMINI_CODE_REDIRECT
call resp%set_url("/players.gmi")
- else if(req%location == "/jobs.gmi") then
- ! Used for paging - send it back
+ else if(req%location == "/jobs.gmi" .or. req%location == "/releases.gmi") then
+ ! Used for paging (jobs) or subdirs (releases) - send it back
resp = external_request_templated(req)
else if(trim(first) == "instructions") then
@@ -701,6 +787,8 @@ contains
else if(trim(req%location) == "/releases.gmi") then
call page%assign('title', 'Releases')
+ contents => generate_releases_gemini(req)
+ call page%assign('contents', contents)
else if(trim(req%location) == "/jobs.gmi") then