aboutsummaryrefslogtreecommitdiff
path: root/player/player.F90
diff options
context:
space:
mode:
Diffstat (limited to 'player/player.F90')
-rw-r--r--player/player.F90193
1 files changed, 193 insertions, 0 deletions
diff --git a/player/player.F90 b/player/player.F90
new file mode 100644
index 0000000..0eb5a72
--- /dev/null
+++ b/player/player.F90
@@ -0,0 +1,193 @@
+program player
+use config
+use instructions
+use player_endpoints
+use json_module
+use talking
+
+#ifdef WINDOWS
+use wsa_network, only: windows_network_startup => startup
+#endif
+
+implicit none
+
+ character(len=1024)::url
+ type(json_file)::j
+ logical::work_to_do, json_available
+
+ integer::i_task
+
+#ifdef WINDOWS
+ call windows_network_startup()
+#endif
+
+ call parse_options()
+
+ ! Change directory to the working directory now
+ call chdir(working_directory)
+
+ do while(.true.)
+
+ ! Check in for work
+ call get_check_in_url(url)
+ json_available = request_json(url, j)
+ if(json_available) then
+ work_to_do = work_available(j)
+ end if
+
+ if(work_to_do) then
+
+ ! Task loop
+ call perform_tasks(j)
+
+ else
+
+#ifdef GNU
+ call sleep(50)
+#endif
+
+ end if
+
+ ! Sleep a bit regardless
+#ifdef GNU
+ call sleep(10)
+#endif
+
+ ! Destroy any existing json
+ if(json_available) then
+ call destroy_instructions(j)
+ end if
+
+ end do
+
+contains
+
+ subroutine usage()
+ implicit none
+
+ character(len=256)::pname
+
+ call get_command_argument(0, pname)
+
+ Print *, "Usage: "//trim(pname)//" <options> <captain>"
+ Print *, " "
+ Print *, "captain is the build control server"
+ Print *, " "
+
+ Print *, "Options:"
+ Print *, " -h Display this help"
+ Print *, " -w <dir> Use dir as the working directory"
+ Print *, " -l <log> Use log as the logfile"
+ Print *, " -i <identity> This players identity"
+
+ end subroutine usage
+
+ subroutine parse_options
+ use config
+ implicit none
+
+ character(len=1024)::option
+ integer::slen
+ integer::i
+
+ identity = " "
+
+ i = 1
+ do while(i <= command_argument_count())
+ call get_command_argument(i, option)
+
+ if(option(1:1) /= "-") then
+ captain = option
+
+ else if(trim(option) == "-h") then
+ call usage()
+ stop
+
+ else if(trim(option) == "-w") then
+ i = i + 1
+ call get_command_argument(i, length=slen)
+ allocate(character(len=slen) :: working_directory)
+ call get_command_argument(i, working_directory)
+
+ else if(trim(option) == "-l") then
+ i = i + 1
+ call get_command_argument(i, length=slen)
+ allocate(character(len=slen) :: logfile)
+ call get_command_argument(i, logfile)
+
+ else if(trim(option) == "-i") then
+ i = i + 1
+ call get_command_argument(i, identity)
+
+ end if
+
+ i = i + 1
+ end do
+
+ ! Assign working directory from command if not specified
+ if(.not. associated(working_directory)) then
+ call get_command_argument(0, length=slen)
+ allocate(character(len=slen) :: working_directory)
+ call get_command_argument(i, working_directory)
+ i = index(working_directory, "/", back=.true.)
+ if(i == 0) then
+ i = index(working_directory, "/", back=.true.)
+ endif
+ if(i == 0) then
+ Print *, "Could not determine working_directory"
+ stop
+ else
+ working_directory(i:slen) = ' '
+ end if
+ end if
+
+ ! Assign a temporary directory and file for a log file
+ ! NOTE: will fail on Windows
+ if(.not. associated(logfile)) then
+ allocate(character(len=256) :: logfile)
+ logfile = "/tmp/levitating.log"
+ end if
+
+ ! Assign this computer an identity if not explicitly specified
+ if(len_trim(identity) == 0) then
+#ifdef GNU
+ call hostnm(identity)
+#else
+ Print *, "Could not determine host identity"
+ stop
+#endif
+ end if
+
+ end subroutine parse_options
+
+ function request_json(url, j)
+ use json_module
+ use gemini_protocol
+ use instructions, only: parse_instructions
+ use talking, only: request_to_temporary_file
+ use utilities, only: delete_file
+ implicit none
+
+ logical::request_json
+ character(*), intent(in)::url
+ type(json_file), intent(out)::j
+
+ character(:), pointer::filename
+ integer::status_code
+
+ status_code = request_to_temporary_file(url, filename)
+ if(status_code == STATUS_SUCCESS) then
+ j = parse_instructions(filename)
+ call delete_file(filename)
+ else
+ request_json = .false.
+ end if
+
+ if(associated(filename)) then
+ call delete_file(filename)
+ deallocate(filename)
+ end if
+
+ end function request_json
+
+end program player \ No newline at end of file