From fb7136be64188cab7db34ac3ad6c8f27098173de Mon Sep 17 00:00:00 2001 From: Jeffrey Armstrong Date: Wed, 29 Jun 2022 08:33:07 -0400 Subject: Initial work to show artifacts on job pages. --- captain/db.f90 | 77 +++++++++++++++++++++++++++++++++++++++++++++++++ captain/external.f90 | 8 ++++- captain/special.f90 | 34 ++++++++++++++++++++++ captain/sql/create.sql | 1 + captain/web.f90 | 21 ++++++++++++++ common/protocol.f90 | 13 +++++++-- player/instructions.f90 | 10 +++---- player/tasks.f90 | 20 ++++++++++--- 8 files changed, 171 insertions(+), 13 deletions(-) diff --git a/captain/db.f90 b/captain/db.f90 index 90fb4e1..c3f30c4 100644 --- a/captain/db.f90 +++ b/captain/db.f90 @@ -1747,5 +1747,82 @@ contains end function is_valid_session_db + subroutine add_job_upload_db(job_id, category, filename) + implicit none + + integer, intent(in)::job_id + character(len=*), intent(in)::category, filename + + type(sqlite3_stmt)::stmt + + if(stmt%prepare(db, "INSERT INTO job_uploads(job, category, filename) VALUES(?, ?, ?)") == SQLITE_OK) then + + if(stmt%bind_int(1, job_id) == SQLITE_OK .and. stmt%bind_text(2, category) == SQLITE_OK .and. & + stmt%bind_text(3, filename) == SQLITE_OK) & + then + + call stmt%step_now() + + end if + call stmt%finalize() + end if + + end subroutine add_job_upload_db + + function get_job_upload_count_by_category_db(job_id, category) result(entries) + implicit none + + integer, intent(in)::job_id + character(len=*), intent(in)::category + integer::entries + type(sqlite3_stmt)::stmt + + entries = 0 + + if(stmt%prepare(db, "SELECT COUNT(*) FROM job_uploads WHERE job=? AND category=?") == SQLITE_OK) then + if(stmt%bind_int(1, job_id) == SQLITE_OK .and. stmt%bind_text(2, category) == SQLITE_OK) then + if(stmt%step() == SQLITE_ROW) then + entries = stmt%column_int(0) + end if + end if + call stmt%finalize() + end if + + end function get_job_upload_count_by_category_db + + function get_job_uploads_by_category_db(job_id, category, count) result(res) + implicit none + + integer, intent(in)::job_id + character(len=*), intent(in)::category + integer, intent(out), optional::count + + character(len=FILENAME_NAME_LENGTH), dimension(:), pointer::res + + type(sqlite3_stmt)::stmt + integer::entries, i + + res => null() + entries = get_job_upload_count_by_category_db(job_id, category) + + if(entries > 0) then + allocate(res(entries)) + + i = 1 + if(stmt%prepare(db, "SELECT filename FROM job_uploads WHERE job=? AND category=?") == SQLITE_OK) then + if(stmt%bind_int(1, job_id) == SQLITE_OK .and. stmt%bind_text(2, category) == SQLITE_OK) then + do while(stmt%step() == SQLITE_ROW) + call stmt%column_text(0, res(i)) + i = i + 1 + end do + end if + end if + end if + + if(present(count)) then + count = entries + end if + + end function get_job_uploads_by_category_db end module captain_db diff --git a/captain/external.f90 b/captain/external.f90 index 07f52cb..2f7041e 100644 --- a/captain/external.f90 +++ b/captain/external.f90 @@ -1038,7 +1038,7 @@ contains end if if(associated(fullpath)) then - + ! Write the file call write_log("Storing titan file to "//trim(fullpath), LOG_DEBUG) @@ -1048,6 +1048,12 @@ contains call resp%set_body_contents(RESPONSE_JSON_OKAY) resp%body_mimetype = "text/plain" + if(req%q%has_key("job")) then + call write_log("Ok, log") + call report_upload(req) + call write_log("Upload logged?") + end if + else resp%code = GEMINI_CODE_TEMPFAIL diff --git a/captain/special.f90 b/captain/special.f90 index 553378e..4d8640f 100644 --- a/captain/special.f90 +++ b/captain/special.f90 @@ -129,4 +129,38 @@ contains end function get_full_filename_from_request + subroutine report_upload(req) + use captain_db + use server_response + use logging + implicit none + + class(request), intent(in)::req + integer::job_id, ierr + character(len=:), pointer:: job_text + + character(256)::first + character(1024)::remaining + integer::i + + job_text => req%q%get_value("job") + call write_log("jobtext: "//trim(job_text)) + if(associated(job_text)) then + read(job_text, *, iostat=ierr) job_id + if(ierr == 0) then + call write_log("jobid ok") + call req%path_component(1, first) + i = index(req%location, trim(first)) + i = i + len_trim(first) + 1 + remaining = req%location(i:len_trim(req%location)) + + + call write_log("Writing job upload for: "//trim(first)//" -> "//trim(remaining)) + call add_job_upload_db(job_id, trim(first), trim(remaining)) + + end if + end if + + end subroutine report_upload + end module special_filenames diff --git a/captain/sql/create.sql b/captain/sql/create.sql index 323efd0..f8c674f 100644 --- a/captain/sql/create.sql +++ b/captain/sql/create.sql @@ -25,3 +25,4 @@ CREATE TABLE sessions(user INTEGER, session TEXT NOT NULL, accessed TEXT NOT NUL CREATE VIEW session_auth AS SELECT sessions.session, users.username, users.level FROM sessions INNER JOIN users ON sessions.user = users.id; +CREATE TABLE job_uploads(job INTEGER, category TEXT NOT NULL, filename TEXT NOT NULL, FOREIGN KEY(job) REFERENCES jobs(id)); diff --git a/captain/web.f90 b/captain/web.f90 index e7ade4f..0bd21ee 100644 --- a/captain/web.f90 +++ b/captain/web.f90 @@ -729,6 +729,7 @@ contains function generate_one_job_html(req) result(res) use captain_db + use config use server_response use special_filenames, only: get_task_result_static_filename use request_utils, only: get_status_utf8, get_player_link => player_link, & @@ -749,6 +750,7 @@ contains character(len=:), pointer::task_results_filename, one_link, local_task_results_filename character(len=:), pointer::player_link, instruction_link + character(len=FILENAME_NAME_LENGTH), dimension(:), pointer::releases logical::file_exists res => null() @@ -817,6 +819,25 @@ contains res = trim(res)//nl//nl//"

None reported yet

" end if + if(get_job_upload_count_by_category_db(job_id, "releases") > 0 .and. & + req%auth_level >= global_permissions%get("access-releases")) & + then + + res = trim(res)//nl//"

Releases

"//nl//"" + + end if + else allocate(character(len=64) :: res) diff --git a/common/protocol.f90 b/common/protocol.f90 index 25050cb..9fc1171 100644 --- a/common/protocol.f90 +++ b/common/protocol.f90 @@ -207,7 +207,7 @@ contains end function request_url - function titan_post_url(url, unit_number, file_length, token, is_plain_text) result(returncode) + function titan_post_url(url, unit_number, file_length, token, is_plain_text, extra) result(returncode) use request use iso_c_binding use utilities, only: read_into_buffer @@ -218,6 +218,7 @@ contains character(*), intent(in)::token integer, intent(in)::unit_number logical, intent(in), optional::is_plain_text + character(*), intent(in), optional::extra integer::port integer::returncode @@ -230,7 +231,7 @@ contains type(connection)::conn character, dimension(BUFFER_SIZE)::buffer - logical, dimension(4)::successes + logical, dimension(5)::successes integer::i, bytes_read, bytes_written, total_written ! For direct processing of the reponse line @@ -271,10 +272,16 @@ contains trimming=.false., allow_trailing_null=.false.) end if + if(present(extra)) then + successes(4) = send_string(conn%ssl, ";"//trim(extra), trimming=.false., allow_trailing_null=.false.) + else + successes(4) = .true. + end if + write(file_length_text, '(I14)') file_length file_length_text = adjustl(file_length_text) - successes(4) = send_string(conn%ssl, & + successes(5) = send_string(conn%ssl, & ";size="//trim(file_length_text)//c_carriage_return//c_new_line, & trimming=.false., & allow_trailing_null=.false.) diff --git a/player/instructions.f90 b/player/instructions.f90 index f9be1f9..e81a46b 100644 --- a/player/instructions.f90 +++ b/player/instructions.f90 @@ -263,14 +263,14 @@ contains end subroutine get_task_operation - function perform_task(j, i, capture_filename) result(success) + function perform_task(j, job_id, i, capture_filename) result(success) use json_module use tasks use utilities implicit none class(json_file)::j - integer, intent(in)::i + integer, intent(in)::job_id, i character(len=:), pointer, intent(out)::capture_filename logical::success @@ -304,9 +304,9 @@ contains success = .false. else if(index(filename, "*") > 0 .or. index(filename, "?") > 0) then - success = upload_glob(url, filename) + success = upload_glob(url, filename, job_id) else - success = upload(url, filename) + success = upload(url, filename, job_id) end if end if @@ -419,7 +419,7 @@ contains Print *, "Reporting: "//trim(url) server_status = request_to_ignored(url) - res = perform_task(j, i, captured_filename) + res = perform_task(j, job_id, i, captured_filename) if(associated(captured_filename)) then if(res) then diff --git a/player/tasks.f90 b/player/tasks.f90 index 832e345..1084329 100644 --- a/player/tasks.f90 +++ b/player/tasks.f90 @@ -93,13 +93,14 @@ contains end function shell - function upload_glob(url, mask) result(res) + function upload_glob(url, mask, job_id) result(res) use utilities implicit none logical::res character(*), intent(in)::url character(*), intent(in)::mask + integer, intent(in)::job_id character(DIR_LIST_STRING_LENGTH), dimension(:), pointer::files logical, dimension(:), allocatable::statuses @@ -130,7 +131,7 @@ contains call combine_paths(dir, files(i), fullname) end if - statuses(i) = upload(url, fullname) + statuses(i) = upload(url, fullname, job_id) end do res = all(statuses) @@ -152,7 +153,7 @@ contains end function upload_glob - function upload(url, source_filename) result(res) + function upload(url, source_filename, job_id) result(res) use config, only: token, captain, identity use gemini_protocol, only: titan_post_url, STATUS_SUCCESS, STATUS_TEMPFAIL implicit none @@ -160,8 +161,10 @@ contains logical::res character(*), intent(in)::url character(*), intent(in)::source_filename + integer, intent(in), optional::job_id character(len=:), allocatable::mod_url + character(len=32)::job_id_keyval integer(kind=8)::file_size integer::unit_number, istatus, url_length, i @@ -210,8 +213,17 @@ contains end if if(istatus == 0) then + Print *, "Writing "//trim(mod_url) - istatus = titan_post_url(mod_url, unit_number, file_size, trim(identity)//":"//trim(token)) + + if(present(job_id)) then + write(job_id_keyval, *) job_id + job_id_keyval = "job="//trim(adjustl(job_id_keyval)) + istatus = titan_post_url(mod_url, unit_number, file_size, trim(identity)//":"//trim(token), & + extra=trim(job_id_keyval)) + else + istatus = titan_post_url(mod_url, unit_number, file_size, trim(identity)//":"//trim(token)) + end if Print *, "Response code from server: ", istatus if(istatus == STATUS_TEMPFAIL) then -- cgit v1.2.3