aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--captain/external.f9092
-rw-r--r--common/utilities.F9026
2 files changed, 109 insertions, 9 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
diff --git a/common/utilities.F90 b/common/utilities.F90
index 961a349..ddc0c79 100644
--- a/common/utilities.F90
+++ b/common/utilities.F90
@@ -6,6 +6,8 @@ module utilities
character, parameter::dir_sep = '/'
#endif
+ integer, parameter::DIR_LIST_STRING_LENGTH = 128
+
interface replace_field
module procedure replace_field_text
module procedure replace_field_int
@@ -276,7 +278,7 @@ contains
implicit none
character(*), intent(in)::directory
- character(1024), dimension(:), pointer::res
+ character(DIR_LIST_STRING_LENGTH), dimension(:), pointer::res
character(80)::line
character(len=:), pointer::tempfile
integer::dcount, unum, ierr, i
@@ -288,6 +290,10 @@ contains
wait=.true.)
open(newunit=unum, file=tempfile, action='read')
+
+ ! First line is "total ###"
+ read(unum, '(A)', iostat=ierr) line
+
dcount = 0
read(unum, '(A)', iostat=ierr) line
do while(ierr == 0)
@@ -303,14 +309,14 @@ contains
allocate(res(dcount))
! Now call ls, but group directories first
- call execute_command_line("ls -g "//trim(directory)//" > "//trim(tempfile), &
+ call execute_command_line("ls --group-directories-first "//trim(directory)//" > "//trim(tempfile), &
wait=.true.)
open(newunit=unum, file=tempfile, action='read')
i = 0
read(unum, '(A)', iostat=ierr) line
do while(ierr == 0 .and. i < dcount)
i = i + 1
- call combine_paths(trim(directory), trim(line), res(i))
+ res(i) = trim(line)
read(unum, '(A)', iostat=ierr) line
end do
@@ -325,7 +331,7 @@ contains
implicit none
character(*), intent(in)::directory
- character(1024), dimension(:), pointer::res
+ character(DIR_LIST_STRING_LENGTH), dimension(:), pointer::res
character(80)::line
character(len=:), pointer::tempfile
integer::dcount, total_count, unum, ierr, i
@@ -337,6 +343,10 @@ contains
wait=.true.)
open(newunit=unum, file=tempfile, action='read')
+
+ ! First line is "total ###"
+ read(unum, '(A)', iostat=ierr) line
+
dcount = 0
total_count = 0
read(unum, '(A)', iostat=ierr) line
@@ -354,16 +364,18 @@ contains
allocate(res(total_count - dcount))
! Now call ls, but group directories first
- call execute_command_line("ls -g "//trim(directory)//" > "//trim(tempfile), &
+ call execute_command_line("ls --group-directories-first "//trim(directory)//" > "//trim(tempfile), &
wait=.true.)
open(newunit=unum, file=tempfile, action='read')
+ i = 0
read(unum, '(A)', iostat=ierr) line
- do while(ierr == 0 .and. i < dcount)
+ do while(ierr == 0 .and. i <= total_count)
i = i + 1
if(i > dcount) then
- call combine_paths(trim(directory), trim(line), res(i-dcount))
+ res(i-dcount) = trim(line)
end if
+
read(unum, '(A)', iostat=ierr) line
end do