Commit 812cd760 authored by Kurzenberger's avatar Kurzenberger
Browse files

deployed recommendations

1 merge request!1Coding style and recommendations
Showing with 466 additions and 355 deletions
+466 -355
No preview for this file type
......@@ -32,6 +32,26 @@ class DbUtils {
*/
private const TABLE_RESULT = "assignsubmission_dta_result";
private const TABLE_RECOMMENDATIONS = "assignsubmission_dta_recommendations";
/**
* Gets the recommendations for a given submission.
*
* @param int $submissionid ID of the submission
* @return array list of recommendations
*/
public static function get_recommendations_from_database(int $assignmentid,int $submissionid ): array {
global $DB;
// Query the database to get all recommendations for the given submission id.
$records = $DB->get_records(self::TABLE_RECOMMENDATIONS, [
'assignment_id' => $assignmentid,
'submission_id' => $submissionid,
]);
return $records;
}
/**
* gets summary with all corresponding result entries
*
......@@ -83,6 +103,52 @@ class DbUtils {
return $summary;
}
public static function storeRecommendationstoDatabase(
int $assignmentid,
int $submissionid,
array $recommendations
): void {
global $DB;
error_log(print_r($recommendations,true));
// Prepare recommendations to persist to array.
$recommendationrecords = [];
foreach ($recommendations as $recommendation) {
$record = new stdClass();
$record->assignment_id = $assignmentid;
$record->submission_id = $submissionid;
$record->topic = $recommendation['topic'];
$record->url = $recommendation['url'];
$record->exercise_name = $recommendation['exercise_name'];
$record->difficulty = $recommendation['difficulty'];
$record->score = $recommendation['score'];
$recommendationrecords[] = $record;
}
error_log("Das sind die Recommendationrecords.");
error_log(print_r($recommendationrecords,true));
// If recommendations already exist, delete old values beforehand.
$existingrecords = $DB->get_record('assignsubmission_dta_recommendations', [
'assignment_id' => $assignmentid,
'submission_id' => $submissionid,
]);
if ($existingrecords) {
$DB->delete_records('assignsubmission_dta_recommendations', [
'assignment_id' => $assignmentid,
'submission_id' => $submissionid,
]);
}
// Create new recommendation entries.
foreach ($recommendationrecords as $rec) {
error_log("Insert record");
error_log(print_r($rec,true));
$DB->insert_record('assignsubmission_dta_recommendations', $rec);
}
}
/**
* save given result summary and single results to database
......@@ -107,8 +173,7 @@ class DbUtils {
$summaryrecord->global_stacktrace = $summary->globalstacktrace;
$summaryrecord->successful_competencies = $summary->successfultestcompetencies;
$summaryrecord->tested_competencies = $summary->overalltestcompetencies;
$summaryrecord->recommendations = $summary->recommendations;
// Prepare results to persist to array.
$resultrecords = [];
foreach ($summary->results as $r) {
......@@ -161,6 +226,8 @@ class DbUtils {
$DB->delete_records(self::TABLE_RESULT, null);
$DB->delete_records(self::TABLE_SUMMARY, null);
$DB->delete_records(self::TABLE_RECOMMENDATIONS, null);
}
}
......@@ -57,7 +57,6 @@ class provider implements \core_privacy\local\metadata\provider,
'global_stacktrace' => 'privacy:metadata:assignsubmission_dta_summary:global_stacktrace',
'successful_competencies' => 'privacy:metadata:assignsubmission_dta_summary:successful_competencies',
'tested_competencies' => 'privacy:metadata:assignsubmission_dta_summary:tested_competencies',
'recommendations' => 'privacy:metadata:assignsubmission_dta_summary:recommendations',
],
'privacy:metadata:assignsubmission_dta_summary'
......
This diff is collapsed.
......@@ -11,7 +11,6 @@
<FIELD NAME="submission_id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="successful_competencies" TYPE="char" LENGTH="80" NOTNULL="false"/>
<FIELD NAME="tested_competencies" TYPE="char" LENGTH="80" NOTNULL="false"/>
<FIELD NAME="recommendations" TYPE="char" LENGTH="160" NOTNULL="false"/>
<FIELD NAME="timestamp" TYPE="int" LENGTH="10"/>
<FIELD NAME="global_stacktrace" TYPE="text"/>
</FIELDS>
......@@ -21,6 +20,23 @@
<KEY NAME="fk_submission" TYPE="foreign" FIELDS="submission_id" REFTABLE="assign_submission" REFFIELDS="id" COMMENT="The submission this summary relates to."/>
</KEYS>
</TABLE>
<TABLE NAME="assignsubmission_dta_recommendations" COMMENT="Stores recommendation data">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" COMMENT="Primary Key" />
<FIELD NAME="assignment_id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="submission_id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="topic" TYPE="char" LENGTH="255" NOTNULL="true" COMMENT="Recommendation Topic" />
<FIELD NAME="exercise_name" TYPE="char" LENGTH="255" NOTNULL="true" COMMENT="Exercise Name" />
<FIELD NAME="url" TYPE="char" LENGTH="255" NOTNULL="true" COMMENT="Exercise URL" />
<FIELD NAME="difficulty" TYPE="number" LENGTH="10" NOTNULL="true" COMMENT="Exercise Difficulty" />
<FIELD NAME="score" TYPE="number" LENGTH="10" NOTNULL="true" COMMENT="Exercise Score" />
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
<KEY NAME="fk_assignment" TYPE="foreign" FIELDS="assignment_id" REFTABLE="assign" REFFIELDS="id" COMMENT="The assignment instance this recommendations relates to"/>
<KEY NAME="fk_submission" TYPE="foreign" FIELDS="submission_id" REFTABLE="assign_submission" REFFIELDS="id" COMMENT="The submission this recommendations relates to."/>
</KEYS>
</TABLE>
<TABLE NAME="assignsubmission_dta_result" COMMENT="DTA testrun single test results">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
......
......@@ -151,7 +151,6 @@ $string["privacy:metadata:assignsubmission_dta_summary:timestamp"] = "Date and t
$string["privacy:metadata:assignsubmission_dta_summary"] = "Stack trace of the compilation and test if major problems occur";
$string["privacy:metadata:assignsubmission_dta_summary:successful_competencies"] = "List of the successfully tested competencies";
$string["privacy:metadata:assignsubmission_dta_summary:tested_competencies"] = "List of the tested competencies";
$string["privacy:metadata:assignsubmission_dta_summary:recommendations"] = "List of recommendations after submitting the code";
$string["privacy:metadata:assignsubmission_dta_summary"] = "Summary of Dockerized Test Agent (DTA) results";
$string["privacy:metadata:assignsubmission_dta_result:package_name"] = "Package name of individual test";
$string["privacy:metadata:assignsubmission_dta_result:class_name"] = "Class name of individual test";
......@@ -165,3 +164,12 @@ $string["privacy:metadata:assignsubmission_dta_result:line_number"] = "Line numb
$string["privacy:metadata:assignsubmission_dta_result:position"] = "Position of failed individual compilation or test";
$string["privacy:metadata:assignsubmission_dta_result"] = "Individual Dockerized Test Agent (DTA) results";
$string["privacy:metadata:dta_backend"] = "Dockerized Test Agent (DTA) backend ReST web service";
//PLUGIN
$string['recommendations'] = 'Recommendations';
$string['topic'] = 'Topic';
$string['exercise_name'] = 'Exercise Name';
$string['url'] = 'URL';
$string['difficulty'] = 'Difficulty';
$string['score'] = 'Score';
......@@ -240,66 +240,82 @@ class assign_submission_dta extends assign_submission_plugin {
return count($files);
}
/**
* Save data to the database
*
* @param stdClass $submission
* @param stdClass $data
* @return bool
*/
public function save(stdClass $submission, stdClass $data) {
$data = file_postupdate_standard_filemanager(
$data,
'tasks',
$this->get_file_options(false),
$this->assignment->get_context(),
self::COMPONENT_NAME,
self::ASSIGNSUBMISSION_DTA_FILEAREA_SUBMISSION,
$submission->id
);
/**
* Save data to the database
*
* @param stdClass $submission
* @param stdClass $data
* @return bool
*/
public function save(stdClass $submission, stdClass $data) {
$data = file_postupdate_standard_filemanager(
$data,
'tasks',
$this->get_file_options(false),
$this->assignment->get_context(),
self::COMPONENT_NAME,
self::ASSIGNSUBMISSION_DTA_FILEAREA_SUBMISSION,
$submission->id
);
// If submission is empty leave directly.
if ($this->is_empty($submission)) {
return true;
}
// If submission is empty leave directly.
if ($this->is_empty($submission)) {
return true;
}
// Get submitted files.
$fs = get_file_storage();
$files = $fs->get_area_files(
// Id of current assignment.
$this->assignment->get_context()->id,
self::COMPONENT_NAME,
self::ASSIGNSUBMISSION_DTA_FILEAREA_SUBMISSION,
$submission->id,
'id',
false
);
// Check if a file is uploaded.
if (empty($files)) {
\core\notification::error(get_string("no_submissionfile_warning", self::COMPONENT_NAME));
return true;
}
// Get submitted files.
$fs = get_file_storage();
$files = $fs->get_area_files(
// Id of current assignment.
$this->assignment->get_context()->id,
self::COMPONENT_NAME,
self::ASSIGNSUBMISSION_DTA_FILEAREA_SUBMISSION,
$submission->id,
'id',
false
);
// Get the file.
$file = reset($files);
// Check if a file is uploaded.
if (empty($files)) {
\core\notification::error(get_string("no_submissionfile_warning", self::COMPONENT_NAME));
return true;
}
// Send file to backend.
$response = DtaBackendUtils::send_submission_to_backend($this->assignment, $submission->id, $file);
// Get the file.
$file = reset($files);
// With a null response, return an error.
if (is_null($response)) {
return false;
}
// Send file to backend.
$response = DtaBackendUtils::send_submission_to_backend($this->assignment, $submission->id, $file);
// Convert received json to valid class instances.
$resultsummary = DtaResultSummary::decodejson($response);
// Log an error message.
$recommendations = DtaResultSummary::decodeJsonRecommendation($response);
// With a null response, return an error.
if (is_null($response)) {
return false;
}
error_log(print_r($recommendations,true));
// Convert received json to valid class instances.
$resultsummary = DtaResultSummary::decodejson($response);
// Persist new results to database.
DbUtils::storeresultsummarytodatabase($this->assignment->get_instance()->id, $submission->id, $resultsummary);
return true;
}
// Persist new results to database.
DbUtils::storeresultsummarytodatabase($this->assignment->get_instance()->id, $submission->id, $resultsummary);
// Store the array of records in the database.
DbUtils::storeRecommendationstoDatabase($this->assignment->get_instance()->id, $submission->id, $recommendations);
return true;
}
/**
* Display a short summary of the test results of the submission
......
......@@ -147,6 +147,7 @@ class DtaResultSummary {
*/
public static function decodejson(string $jsonstring): DtaResultSummary {
$response = json_decode($jsonstring);
$summary = new DtaResultSummary();
$summary->timestamp = $response->timestamp;
......@@ -160,6 +161,35 @@ class DtaResultSummary {
return $summary;
}
public static function decodeJsonRecommendation(string $jsonstring): array {
// Decode the JSON string into a PHP object
$response = json_decode($jsonstring);
error_log("decodeJsonRecommendation");
error_log(print_r($response, true));
// Initialize an empty array to store recommendations
$recommendations = [];
// Loop through the recommendations in the response
if (!empty($response->recommendations)) {
foreach ($response->recommendations as $recommendation) {
// For each recommendation, create an associative array with the properties
$recommendations[] = [
'topic' => $recommendation->topic ?? null,
'url' => $recommendation->exerciseName ?? null,
'exercise_name' => $recommendation->url ?? null,
'difficulty' => $recommendation->difficulty ?? null,
'score' => $recommendation->score ?? null
];
}
}
error_log(print_r($recommendations,true));
// Return the array of recommendations
return $recommendations;
}
/**
* Decodes the array of JSON detail results returned by the backend service call into the plugin PHP data structure.
* @param array $jsonarray decoded json array of results array
......
dta1.0.zip 0 → 100644
File added
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment