diff --git a/Assets/Scripts/VitrivrVR/Input/Text/SceneTextInputController.cs b/Assets/Scripts/VitrivrVR/Input/Text/SceneTextInputController.cs
index e927458..8a0972d 100644
--- a/Assets/Scripts/VitrivrVR/Input/Text/SceneTextInputController.cs
+++ b/Assets/Scripts/VitrivrVR/Input/Text/SceneTextInputController.cs
@@ -1,7 +1,5 @@
using UnityEngine;
-using VitrivrVR.Config;
-using Dev.Dres.ClientApi.Model;
-using VitrivrVR.Submission;
+using VitrivrVR.Logging;
namespace VitrivrVR.Input.Text
{
@@ -13,45 +11,43 @@ public class SceneTextInputController : MonoBehaviour
public void InputText(string text)
{
TextInputManager.InputText(text);
- DresClientManager.LogInteraction("keyboard", $"input {text}", QueryEvent.CategoryEnum.TEXT);
+ LoggingController.LogInteraction("keyboard", $"input {text}", Logging.Interaction.TextInput);
}
public void InputBackspace()
{
TextInputManager.InputBackspace();
- DresClientManager.LogInteraction("keyboard", "backspace", QueryEvent.CategoryEnum.TEXT);
+ LoggingController.LogInteraction("keyboard", "backspace", Logging.Interaction.TextInput);
}
-
+
public void InputReturn()
{
TextInputManager.InputReturn();
- DresClientManager.LogInteraction("keyboard", "return", QueryEvent.CategoryEnum.TEXT);
+ LoggingController.LogInteraction("keyboard", "return", Logging.Interaction.TextInput);
}
-
+
public void InputLeftArrow()
{
TextInputManager.InputLeftArrow();
- DresClientManager.LogInteraction("keyboard", "ArrowLeft", QueryEvent.CategoryEnum.TEXT);
+ LoggingController.LogInteraction("keyboard", "ArrowLeft", Logging.Interaction.TextInput);
}
-
+
public void InputRightArrow()
{
TextInputManager.InputRightArrow();
- DresClientManager.LogInteraction("keyboard", "ArrowRight", QueryEvent.CategoryEnum.TEXT);
+ LoggingController.LogInteraction("keyboard", "ArrowRight", Logging.Interaction.TextInput);
}
+
public void InputTabulator()
{
TextInputManager.InputTabulator();
- DresClientManager.LogInteraction("keyboard", "Tabulator", QueryEvent.CategoryEnum.TEXT);
+ LoggingController.LogInteraction("keyboard", "Tabulator", Logging.Interaction.TextInput);
}
public void ReceiveDictationResult(string text)
{
InputText(text);
- if (ConfigManager.Config.dresEnabled)
- {
- DresClientManager.LogInteraction("speechToText", $"input {text} DeepSpeech", QueryEvent.CategoryEnum.TEXT);
- }
+ LoggingController.LogInteraction("speechToText", $"input {text} DeepSpeech", Logging.Interaction.TextInput);
}
}
}
\ No newline at end of file
diff --git a/Assets/Scripts/VitrivrVR/Logging.meta b/Assets/Scripts/VitrivrVR/Logging.meta
new file mode 100644
index 0000000..4d675af
--- /dev/null
+++ b/Assets/Scripts/VitrivrVR/Logging.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: b037eb8c67aa944928d91bb3b60e1885
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/VitrivrVR/Logging/Interaction.cs b/Assets/Scripts/VitrivrVR/Logging/Interaction.cs
new file mode 100644
index 0000000..b6635ce
--- /dev/null
+++ b/Assets/Scripts/VitrivrVR/Logging/Interaction.cs
@@ -0,0 +1,14 @@
+namespace VitrivrVR.Logging
+{
+ public enum Interaction
+ {
+ TextInput,
+ QueryFormulation,
+ Query,
+ QueryManagement,
+ Browsing,
+ Filter,
+ ResultExpansion,
+ Other
+ }
+}
\ No newline at end of file
diff --git a/Assets/Scripts/VitrivrVR/Logging/Interaction.cs.meta b/Assets/Scripts/VitrivrVR/Logging/Interaction.cs.meta
new file mode 100644
index 0000000..12607da
--- /dev/null
+++ b/Assets/Scripts/VitrivrVR/Logging/Interaction.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 003cde0f439d406e8414b0f6020035d4
+timeCreated: 1669973631
\ No newline at end of file
diff --git a/Assets/Scripts/VitrivrVR/Logging/LoggingController.cs b/Assets/Scripts/VitrivrVR/Logging/LoggingController.cs
new file mode 100644
index 0000000..dde3976
--- /dev/null
+++ b/Assets/Scripts/VitrivrVR/Logging/LoggingController.cs
@@ -0,0 +1,259 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Threading;
+using Newtonsoft.Json;
+using Org.Vitrivr.CineastApi.Model;
+using Vitrivr.UnityInterface.CineastApi.Model.Data;
+using VitrivrVR.Config;
+using VitrivrVR.Notification;
+using VitrivrVR.Submission;
+
+namespace VitrivrVR.Logging
+{
+ ///
+ /// Static class for all interaction and usage logs.
+ ///
+ /// The goal of this class is to separate the log sources from different kinds of loggers, such as file and
+ /// competition loggers.
+ ///
+ public static class LoggingController
+ {
+ private static readonly string StartDate = DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss");
+ private static readonly string LogDir = Path.Combine(ConfigManager.Config.logFileLocation, StartDate);
+ private static readonly string ResultLogLocation = Path.Combine(LogDir, "results.txt");
+ private static readonly string SubmissionLogLocation = Path.Combine(LogDir, "submission.txt");
+ private static readonly string InteractionLogLocation = Path.Combine(LogDir, "interactions.txt");
+
+ private static readonly SemaphoreSlim SubmissionLogLock = new(1, 1);
+ private static readonly SemaphoreSlim ResultLogLock = new(1, 1);
+ private static readonly SemaphoreSlim InteractionLogLock = new(1, 1);
+
+ private static long CurrentTimestamp => DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+
+ ///
+ /// Logs ranked results lists for similarity and staged similarity queries.
+ ///
+ /// The order in which the ranked results are displayed (e.g. by segment or object).
+ /// List of ranked results.
+ /// Query response containing the source query.
+ public static void LogQueryResults(string sortOrder, List results, QueryResponse queryResponse)
+ {
+ var timestamp = CurrentTimestamp;
+
+ // Log to DRES
+ if (ConfigManager.Config.dresEnabled)
+ {
+ // Similarity query
+ if (queryResponse.Query != null)
+ {
+ DresClientManager.LogResults(timestamp, sortOrder, results, queryResponse.Query);
+ }
+
+ // Staged query
+ if (queryResponse.StagedQuery != null)
+ {
+ DresClientManager.LogResults(timestamp, sortOrder, results, queryResponse.StagedQuery);
+ }
+ }
+
+ // Log to file
+ if (ConfigManager.Config.writeLogsToFile)
+ {
+ LogQueryResultsToFile(timestamp, sortOrder, results, queryResponse);
+ }
+ }
+
+ ///
+ /// Logs ranked results lists for temporal similarity queries.
+ ///
+ public static void LogQueryResults(string sortOrder, List results,
+ TemporalQueryResponse queryResponse)
+ {
+ var timestamp = CurrentTimestamp;
+
+ // Log to DRES
+ if (ConfigManager.Config.dresEnabled)
+ {
+ DresClientManager.LogResults(timestamp, sortOrder, results, queryResponse.Query);
+ }
+
+ // Log to file
+ if (ConfigManager.Config.writeLogsToFile)
+ {
+ LogQueryResultsToFile(timestamp, sortOrder, results, queryResponse);
+ }
+ }
+
+ public static void LogSubmission(string mediaObjectId, int? frame)
+ {
+ var timestamp = CurrentTimestamp;
+ // Log to file
+ if (ConfigManager.Config.writeLogsToFile)
+ {
+ LogSubmissionToFile(timestamp, mediaObjectId, frame);
+ }
+ }
+
+ public static void LogInteraction(string type, string value, Interaction category)
+ {
+ var timestamp = CurrentTimestamp;
+ var source = new StackTrace().GetFrame(1).GetMethod().ReflectedType?.Name;
+
+ // Log to DRES
+ if (ConfigManager.Config.dresEnabled)
+ {
+ DresClientManager.LogInteraction(timestamp, type, value, category);
+ }
+
+ // Log to file
+ if (ConfigManager.Config.writeLogsToFile)
+ {
+ LogInteractionToFile(timestamp, source, type, value, category.ToString());
+ }
+ }
+
+ #region FileLogger
+
+ private static void EnsureDirectoryExists()
+ {
+ Directory.CreateDirectory(LogDir);
+ }
+
+ private static async void LogQueryResultsToFile(long timestamp, string sortOrder,
+ IEnumerable results,
+ QueryResponse queryResponse)
+ {
+ EnsureDirectoryExists();
+ await ResultLogLock.WaitAsync();
+ try
+ {
+ await using var file = new StreamWriter(ResultLogLocation, true);
+ var serializableResults = results.Select(segment => new Dictionary
+ {
+ { "id", segment.segment.Id },
+ { "score", segment.score.ToString(CultureInfo.InvariantCulture) }
+ });
+ var jsonResults = JsonConvert.SerializeObject(serializableResults, Formatting.None);
+ var jsonQuery = QueryToJson(queryResponse);
+
+ var resultLog =
+ $"{{\"timestamp\":{timestamp},\"sortOrder\":\"{sortOrder}\",\"query\":{jsonQuery},\"results\":{jsonResults}}}";
+ await file.WriteLineAsync(resultLog);
+ }
+ catch (Exception e)
+ {
+ NotificationController.NotifyError($"Error logging to file: {e.Message}", e);
+ }
+ finally
+ {
+ ResultLogLock.Release();
+ }
+ }
+
+ private static async void LogQueryResultsToFile(long timestamp, string sortOrder, List results,
+ TemporalQueryResponse queryResponse)
+ {
+ EnsureDirectoryExists();
+ await ResultLogLock.WaitAsync();
+ try
+ {
+ await using var file = new StreamWriter(ResultLogLocation, true);
+ var jsonResults = JsonConvert.SerializeObject(results, Formatting.None);
+ var jsonQuery = JsonConvert.SerializeObject(queryResponse.Query, Formatting.None);
+
+ var resultLog =
+ $"{{\"timestamp\":{timestamp},\"sortOrder\":\"{sortOrder}\",\"query\":{jsonQuery},\"results\":{jsonResults}}}";
+ await file.WriteLineAsync(resultLog);
+ }
+ catch (Exception e)
+ {
+ NotificationController.NotifyError($"Error logging to file: {e.Message}", e);
+ }
+ finally
+ {
+ ResultLogLock.Release();
+ }
+ }
+
+ private static string QueryToJson(QueryResponse queryResponse)
+ {
+ if (queryResponse.Query != null)
+ {
+ return JsonConvert.SerializeObject(queryResponse.Query, Formatting.None);
+ }
+
+ if (queryResponse.StagedQuery != null)
+ {
+ return JsonConvert.SerializeObject(queryResponse.StagedQuery, Formatting.None);
+ }
+
+ throw new Exception("Query response contains neither similarity nor staged similarity query.");
+ }
+
+ private static async void LogSubmissionToFile(long timestamp, string mediaObjectId, int? frame)
+ {
+ EnsureDirectoryExists();
+ await SubmissionLogLock.WaitAsync();
+ try
+ {
+ await using var file = new StreamWriter(SubmissionLogLocation, true);
+ var dict = new Dictionary
+ {
+ { "timestamp", timestamp.ToString() },
+ { "mediaObjectId", mediaObjectId }
+ };
+ if (frame.HasValue)
+ dict["frame"] = frame.ToString();
+
+ var json = JsonConvert.SerializeObject(dict, Formatting.None);
+
+ await file.WriteLineAsync(json);
+ }
+ catch (Exception e)
+ {
+ NotificationController.NotifyError($"Error logging to file: {e.Message}");
+ }
+ finally
+ {
+ SubmissionLogLock.Release();
+ }
+ }
+
+ private static async void LogInteractionToFile(long timestamp, string source, string type, string value,
+ string category)
+ {
+ EnsureDirectoryExists();
+ await InteractionLogLock.WaitAsync();
+ try
+ {
+ await using var file = new StreamWriter(InteractionLogLocation, true);
+ var dict = new Dictionary
+ {
+ { "timestamp", timestamp.ToString() },
+ { "source", source },
+ { "type", type },
+ { "value", value },
+ { "category", category }
+ };
+
+ var json = JsonConvert.SerializeObject(dict, Formatting.None);
+
+ await file.WriteLineAsync(json);
+ }
+ catch (Exception e)
+ {
+ NotificationController.NotifyError($"Error logging to file: {e.Message}");
+ }
+ finally
+ {
+ InteractionLogLock.Release();
+ }
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/Assets/Scripts/VitrivrVR/Logging/LoggingController.cs.meta b/Assets/Scripts/VitrivrVR/Logging/LoggingController.cs.meta
new file mode 100644
index 0000000..34df72e
--- /dev/null
+++ b/Assets/Scripts/VitrivrVR/Logging/LoggingController.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 413dc264b46c4f46b6df685d1208687a
+timeCreated: 1666274469
\ No newline at end of file
diff --git a/Assets/Scripts/VitrivrVR/Media/Display/CanvasImageDisplay.cs b/Assets/Scripts/VitrivrVR/Media/Display/CanvasImageDisplay.cs
index 714cdba..f82f19c 100644
--- a/Assets/Scripts/VitrivrVR/Media/Display/CanvasImageDisplay.cs
+++ b/Assets/Scripts/VitrivrVR/Media/Display/CanvasImageDisplay.cs
@@ -8,10 +8,12 @@
using Vitrivr.UnityInterface.CineastApi.Model.Data;
using Vitrivr.UnityInterface.CineastApi.Model.Registries;
using VitrivrVR.Config;
+using VitrivrVR.Logging;
using VitrivrVR.Notification;
using VitrivrVR.Submission;
using VitrivrVR.UI;
using VitrivrVR.Util;
+using static VitrivrVR.Logging.Interaction;
namespace VitrivrVR.Media.Display
{
@@ -67,8 +69,10 @@ public override async void Initialize(ScoredSegment scoredSegment, Action onClos
if (ConfigManager.Config.dresEnabled)
{
submitButton.SetActive(true);
- DresClientManager.LogInteraction("imageSequenceDisplay", $"initialized {_mediaObject.Id} {Segment.Id}");
}
+
+ LoggingController.LogInteraction("imageSequenceDisplay", $"initialized {_mediaObject.Id} {Segment.Id}",
+ ResultExpansion);
}
public void Close()
@@ -79,7 +83,7 @@ public void Close()
private void OnDestroy()
{
- DresClientManager.LogInteraction("imageDisplay", $"closed {_mediaObject.Id} {Segment.Id}");
+ LoggingController.LogInteraction("imageDisplay", $"closed {_mediaObject.Id} {Segment.Id}", Other);
}
public async void ToggleMetadata()
@@ -88,7 +92,7 @@ public async void ToggleMetadata()
{
Destroy(_metadataTable);
_metadataShown = false;
- DresClientManager.LogInteraction("mediaSegmentMetadata", $"closed {_mediaObject.Id}");
+ LoggingController.LogInteraction("mediaSegmentMetadata", $"closed {_mediaObject.Id}", Other);
return;
}
@@ -123,7 +127,7 @@ public async void ToggleMetadata()
var uiTableTransform = _metadataTable.GetComponent();
uiTableTransform.sizeDelta = new Vector2(100, 600); // x is completely irrelevant here, since width is auto
- DresClientManager.LogInteraction("mediaObjectMetadata", $"opened {_mediaObject.Id}");
+ LoggingController.LogInteraction("mediaObjectMetadata", $"opened {_mediaObject.Id}", ResultExpansion);
}
public async void ToggleTagList()
@@ -132,7 +136,7 @@ public async void ToggleTagList()
{
Destroy(_tagList.gameObject);
_tagListShown = false;
- DresClientManager.LogInteraction("segmentTags", $"closed {_mediaObject.Id}");
+ LoggingController.LogInteraction("segmentTags", $"closed {_mediaObject.Id}", Other);
return;
}
@@ -157,7 +161,7 @@ public async void ToggleTagList()
tagItem.GetComponentInChildren().text = tagData.Name;
}
- DresClientManager.LogInteraction("segmentTags", $"opened {_mediaObject.Id} {Segment.Id}");
+ LoggingController.LogInteraction("segmentTags", $"opened {_mediaObject.Id} {Segment.Id}", ResultExpansion);
}
public void Submit()
diff --git a/Assets/Scripts/VitrivrVR/Media/Display/CanvasImageSequenceDisplay.cs b/Assets/Scripts/VitrivrVR/Media/Display/CanvasImageSequenceDisplay.cs
index c79d276..5eee4d6 100644
--- a/Assets/Scripts/VitrivrVR/Media/Display/CanvasImageSequenceDisplay.cs
+++ b/Assets/Scripts/VitrivrVR/Media/Display/CanvasImageSequenceDisplay.cs
@@ -8,10 +8,12 @@
using Vitrivr.UnityInterface.CineastApi.Model.Data;
using Vitrivr.UnityInterface.CineastApi.Model.Registries;
using VitrivrVR.Config;
+using VitrivrVR.Logging;
using VitrivrVR.Notification;
using VitrivrVR.Submission;
using VitrivrVR.UI;
using VitrivrVR.Util;
+using static VitrivrVR.Logging.Interaction;
namespace VitrivrVR.Media.Display
{
@@ -31,7 +33,7 @@ public class CanvasImageSequenceDisplay : MediaDisplay
///
/// The number of neighbors to show in the segment view.
///
- private const int MAXNeighbors = 200;
+ private const int MaxNeighbors = 200;
private ScoredSegment _scoredSegment;
private SegmentData Segment => _scoredSegment.segment;
@@ -76,8 +78,10 @@ public override async void Initialize(ScoredSegment scoredSegment, Action onClos
if (ConfigManager.Config.dresEnabled)
{
submitButton.SetActive(true);
- DresClientManager.LogInteraction("imageSequenceDisplay", $"initialized {_mediaObject.Id} {Segment.Id}");
}
+
+ LoggingController.LogInteraction("imageSequenceDisplay", $"initialized {_mediaObject.Id} {Segment.Id}",
+ ResultExpansion);
}
public void Close()
@@ -93,7 +97,7 @@ private void OnDestroy()
Destroy(_objectSegmentView);
}
- DresClientManager.LogInteraction("imageSequenceDisplay", $"closed {_mediaObject.Id} {Segment.Id}");
+ LoggingController.LogInteraction("imageSequenceDisplay", $"closed {_mediaObject.Id} {Segment.Id}", Other);
}
public async void ToggleMetadata()
@@ -102,7 +106,7 @@ public async void ToggleMetadata()
{
Destroy(_metadataTable);
_metadataShown = false;
- DresClientManager.LogInteraction("mediaSegmentMetadata", $"closed {_mediaObject.Id}");
+ LoggingController.LogInteraction("mediaSegmentMetadata", $"closed {_mediaObject.Id}", Other);
return;
}
@@ -137,7 +141,7 @@ public async void ToggleMetadata()
var uiTableTransform = _metadataTable.GetComponent();
uiTableTransform.sizeDelta = new Vector2(100, 600); // x is completely irrelevant here, since width is auto
- DresClientManager.LogInteraction("mediaObjectMetadata", $"opened {_mediaObject.Id}");
+ LoggingController.LogInteraction("mediaObjectMetadata", $"opened {_mediaObject.Id}", ResultExpansion);
}
public async void ToggleTagList()
@@ -146,7 +150,7 @@ public async void ToggleTagList()
{
Destroy(_tagList.gameObject);
_tagListShown = false;
- DresClientManager.LogInteraction("segmentTags", $"closed {_mediaObject.Id}");
+ LoggingController.LogInteraction("segmentTags", $"closed {_mediaObject.Id}", Other);
return;
}
@@ -171,7 +175,7 @@ public async void ToggleTagList()
tagItem.GetComponentInChildren().text = tagData.Name;
}
- DresClientManager.LogInteraction("segmentTags", $"opened {_mediaObject.Id} {Segment.Id}");
+ LoggingController.LogInteraction("segmentTags", $"opened {_mediaObject.Id} {Segment.Id}", ResultExpansion);
}
public async void ShowObjectSegmentView()
@@ -183,8 +187,8 @@ public async void ShowObjectSegmentView()
else
{
var index = await Segment.GetSequenceNumber();
- var min = index - MAXNeighbors;
- var max = index + MAXNeighbors;
+ var min = index - MaxNeighbors;
+ var max = index + MaxNeighbors;
var t = transform;
_objectSegmentView = Instantiate(mediaObjectSegmentViewPrefab, t.position - 0.2f * t.forward, t.rotation);
_objectSegmentView.GetComponentInChildren()
diff --git a/Assets/Scripts/VitrivrVR/Media/Display/CanvasVideoDisplay.cs b/Assets/Scripts/VitrivrVR/Media/Display/CanvasVideoDisplay.cs
index 6e72a50..4448191 100644
--- a/Assets/Scripts/VitrivrVR/Media/Display/CanvasVideoDisplay.cs
+++ b/Assets/Scripts/VitrivrVR/Media/Display/CanvasVideoDisplay.cs
@@ -15,12 +15,14 @@
using Vitrivr.UnityInterface.CineastApi.Model.Registries;
using Vitrivr.UnityInterface.CineastApi.Utils;
using VitrivrVR.Config;
+using VitrivrVR.Logging;
using VitrivrVR.Media.Controller;
using VitrivrVR.Notification;
using VitrivrVR.Query;
using VitrivrVR.Submission;
using VitrivrVR.UI;
using VitrivrVR.Util;
+using static VitrivrVR.Logging.Interaction;
namespace VitrivrVR.Media.Display
{
@@ -116,8 +118,9 @@ public override async void Initialize(ScoredSegment segment, Action onClose)
if (ConfigManager.Config.dresEnabled)
{
submitButton.SetActive(true);
- DresClientManager.LogInteraction("videoPlayer", $"initialized {_mediaObject.Id} {_segment.Id}");
}
+
+ LoggingController.LogInteraction("videoPlayer", $"initialized {_mediaObject.Id} {_segment.Id}", ResultExpansion);
}
public void Close()
@@ -133,7 +136,7 @@ private void OnDestroy()
Destroy(_objectSegmentView);
}
- DresClientManager.LogInteraction("videoPlayer", $"closed {_mediaObject.Id} {_segment.Id}");
+ LoggingController.LogInteraction("videoPlayer", $"closed {_mediaObject.Id} {_segment.Id}", Other);
}
public void ShowObjectSegmentView()
@@ -157,7 +160,7 @@ public async void ToggleMetadata()
{
Destroy(_metadataTable);
_metadataShown = false;
- DresClientManager.LogInteraction("mediaObjectMetadata", $"closed {_mediaObject.Id}");
+ LoggingController.LogInteraction("mediaObjectMetadata", $"closed {_mediaObject.Id}", Other);
return;
}
@@ -194,7 +197,7 @@ public async void ToggleMetadata()
var uiTableTransform = _metadataTable.GetComponent();
uiTableTransform.sizeDelta = new Vector2(100, 600); // x is completely irrelevant here, since width is auto
- DresClientManager.LogInteraction("mediaObjectMetadata", $"opened {_mediaObject.Id}");
+ LoggingController.LogInteraction("mediaObjectMetadata", $"opened {_mediaObject.Id}", ResultExpansion);
}
public async void ToggleTagList()
@@ -203,7 +206,7 @@ public async void ToggleTagList()
{
Destroy(_tagList.gameObject);
_tagListShown = false;
- DresClientManager.LogInteraction("segmentTags", $"closed {_mediaObject.Id}");
+ LoggingController.LogInteraction("segmentTags", $"closed {_mediaObject.Id}", Other);
return;
}
@@ -231,7 +234,7 @@ public async void ToggleTagList()
tagItem.GetComponentInChildren().text = tagData.Name;
}
- DresClientManager.LogInteraction("segmentTags", $"opened {_mediaObject.Id} {segment.Id}");
+ LoggingController.LogInteraction("segmentTags", $"opened {_mediaObject.Id} {segment.Id}", ResultExpansion);
}
public void SubmitCurrentFrame()
@@ -244,7 +247,7 @@ public void SubmitCurrentFrame()
var frame = _videoPlayerController.Frame;
- DresClientManager.SubmitResult(_mediaObject.Id, (int) frame);
+ DresClientManager.SubmitResult(_mediaObject.Id, (int)frame);
}
public void SetVolume(float volume)
@@ -256,7 +259,7 @@ public void QueryByCurrentFrame()
{
var frame = _videoPlayerController.GetCurrentFrame();
var term = QueryTermBuilder.BuildImageTermForCategories(frame, ConfigManager.Config.defaultImageCategories);
- QueryController.Instance.RunQuery(new List {term});
+ QueryController.Instance.RunQuery(new List { term });
}
private void Awake()
@@ -306,12 +309,12 @@ private void Skip(InputAction.CallbackContext context)
UpdateText(time);
}
- DresClientManager.LogInteraction("videoPlayer", $"skipped {_mediaObject.Id} {time} {sign}");
+ LoggingController.LogInteraction("videoPlayer", $"skipped {_mediaObject.Id} {time} {sign}", Browsing);
}
private void Update()
{
- if (_videoPlayerController is {IsPlaying: true})
+ if (_videoPlayerController is { IsPlaying: true })
{
var time = _videoPlayerController.ClockTime;
UpdateProgressIndicator(time);
@@ -324,12 +327,14 @@ public void OnClick(PointerEventData pointerEventData)
if (_videoPlayerController.IsPlaying)
{
_videoPlayerController.Pause();
- DresClientManager.LogInteraction("videoPlayer", $"pause {_mediaObject.Id} {_videoPlayerController.ClockTime}");
+ LoggingController.LogInteraction("videoPlayer", $"pause {_mediaObject.Id} {_videoPlayerController.ClockTime}",
+ Browsing);
}
else
{
_videoPlayerController.Play();
- DresClientManager.LogInteraction("videoPlayer", $"play {_mediaObject.Id} {_videoPlayerController.ClockTime}");
+ LoggingController.LogInteraction("videoPlayer", $"play {_mediaObject.Id} {_videoPlayerController.ClockTime}",
+ Browsing);
}
}
@@ -348,7 +353,8 @@ private void OnClickProgressBar(PointerEventData pointerEventData)
UpdateProgressIndicator(newTime);
UpdateText(newTime);
- DresClientManager.LogInteraction("videoPlayer", $"jump {_mediaObject.Id} {newTime}");
+ LoggingController.LogInteraction("videoPlayer", $"jump {_mediaObject.Id} {newTime}",
+ Browsing);
}
private void SetVideoTime(double time)
@@ -420,7 +426,7 @@ private IEnumerator InstantiateSegmentIndicators(IEnumerable segmentStart
var i = 0;
foreach (var segStart in segmentStarts)
{
- progressTexture.SetPixel((int) (999 * (segStart / _videoPlayerController.Length)), 0, Color.black);
+ progressTexture.SetPixel((int)(999 * (segStart / _videoPlayerController.Length)), 0, Color.black);
i++;
if (i == InstantiationBatch)
{
@@ -442,7 +448,7 @@ private void ErrorEncountered(VideoPlayer videoPlayer, string error)
private void UpdateProgressIndicator(double time)
{
progressIndicator.anchoredPosition =
- new Vector2((float) (progressBar.rect.width * time / _videoPlayerController.Length), 0);
+ new Vector2((float)(progressBar.rect.width * time / _videoPlayerController.Length), 0);
}
private async void UpdateText(double time)
@@ -476,8 +482,8 @@ private async Task GetCurrentSegment(double time)
private void SetSegmentIndicator(double start, double end, double length, RectTransform rt)
{
var rect = progressBar.rect;
- rt.anchoredPosition = new Vector2((float) (rect.width * start / length), 0);
- rt.sizeDelta = new Vector2((float) (rect.width * (end - start) / length), 0);
+ rt.anchoredPosition = new Vector2((float)(rect.width * start / length), 0);
+ rt.sizeDelta = new Vector2((float)(rect.width * (end - start) / length), 0);
}
}
}
\ No newline at end of file
diff --git a/Assets/Scripts/VitrivrVR/Media/Display/MediaObjectSegmentView.cs b/Assets/Scripts/VitrivrVR/Media/Display/MediaObjectSegmentView.cs
index 61e29df..9e801a3 100644
--- a/Assets/Scripts/VitrivrVR/Media/Display/MediaObjectSegmentView.cs
+++ b/Assets/Scripts/VitrivrVR/Media/Display/MediaObjectSegmentView.cs
@@ -8,8 +8,9 @@
using Vitrivr.UnityInterface.CineastApi.Model.Data;
using VitrivrVR.Interaction.System;
using VitrivrVR.Interaction.System.Grab;
+using VitrivrVR.Logging;
using VitrivrVR.Media.Controller;
-using VitrivrVR.Submission;
+using static VitrivrVR.Logging.Interaction;
namespace VitrivrVR.Media.Display
{
@@ -42,7 +43,8 @@ private void OnTriggerEnter(Collider other)
if (other.TryGetComponent(out var interactor))
{
_enteredInteractors.Add(interactor, -1);
- DresClientManager.LogInteraction("videoSummary", $"browse started {_mediaObject.Id}");
+ LoggingController.LogInteraction("videoSummary", $"browse started {_mediaObject.Id} {interactor.name}",
+ Browsing);
}
}
@@ -57,7 +59,8 @@ private void OnTriggerExit(Collider other)
}
_enteredInteractors.Remove(interactor);
- DresClientManager.LogInteraction("videoSummary", $"browse stopped {_mediaObject.Id}");
+ LoggingController.LogInteraction("videoSummary", $"browse stopped {_mediaObject.Id} {interactor.name}",
+ Browsing);
}
}
@@ -87,7 +90,7 @@ private void OnTriggerExit(Collider other)
private void OnDestroy()
{
- DresClientManager.LogInteraction("videoSummary", $"closed {_mediaObject.Id}");
+ LoggingController.LogInteraction("videoSummary", $"closed {_mediaObject.Id}", Other);
}
public async void Initialize(ObjectData mediaObject, Action onSegmentSelection, int min = 0,
@@ -116,7 +119,7 @@ await Task.WhenAll(segments.Select(async segment =>
StartCoroutine(InstantiateSegmentIndicators(segmentInfo, segmentInfo.Length));
// TODO: Translate type in DresClientManager to support other media object types
- DresClientManager.LogInteraction("videoSummary", $"initialized {_mediaObject.Id}");
+ LoggingController.LogInteraction("videoSummary", $"initialized {_mediaObject.Id}", ResultExpansion);
}
public override void OnInteraction(Transform interactor, bool start)
@@ -125,7 +128,8 @@ public override void OnInteraction(Transform interactor, bool start)
var rawIndex = GetSegmentIndex(interactor);
var segmentIndex = rawIndex + _minIndex - 1;
_onSegmentSelection(segmentIndex, interactor.position);
- DresClientManager.LogInteraction("videoSummary", $"selected {_mediaObject.Id} {segmentIndex}");
+ LoggingController.LogInteraction("videoSummary", $"selected {_mediaObject.Id} {segmentIndex} {interactor.name}",
+ ResultExpansion);
}
private IEnumerator InstantiateSegmentIndicators(IEnumerable<(SegmentData segment, int seqNum)> segmentInfo,
@@ -139,7 +143,7 @@ private IEnumerator InstantiateSegmentIndicators(IEnumerable<(SegmentData segmen
var thumbnail = Instantiate(thumbnailPrefab, transform);
thumbnail.url = thumbnailUrl;
- thumbnail.transform.localPosition = Vector3.forward * ((float) (seqNum - _minIndex) / numSegments - 0.5f);
+ thumbnail.transform.localPosition = Vector3.forward * ((float)(seqNum - _minIndex) / numSegments - 0.5f);
_thumbnails[seqNum - _minIndex] = thumbnail;
@@ -192,7 +196,7 @@ private void SetThumbnailHeight(int index, bool selected)
private int GetSegmentIndex(Transform other)
{
var otherTransform = transform.InverseTransformPoint(other.position);
- return (int) Mathf.Min(Mathf.Max((otherTransform.z + 0.5f) * _thumbnails.Length, 0), _thumbnails.Length - 1);
+ return (int)Mathf.Min(Mathf.Max((otherTransform.z + 0.5f) * _thumbnails.Length, 0), _thumbnails.Length - 1);
}
}
}
\ No newline at end of file
diff --git a/Assets/Scripts/VitrivrVR/Query/Display/CylinderObjectQueryDisplay.cs b/Assets/Scripts/VitrivrVR/Query/Display/CylinderObjectQueryDisplay.cs
index 17aa41d..3700a80 100644
--- a/Assets/Scripts/VitrivrVR/Query/Display/CylinderObjectQueryDisplay.cs
+++ b/Assets/Scripts/VitrivrVR/Query/Display/CylinderObjectQueryDisplay.cs
@@ -2,13 +2,14 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
-using Vitrivr.UnityInterface.CineastApi.Model.Data;
using UnityEngine;
using UnityEngine.InputSystem;
+using Vitrivr.UnityInterface.CineastApi.Model.Data;
using VitrivrVR.Config;
+using VitrivrVR.Logging;
using VitrivrVR.Media.Display;
using VitrivrVR.Notification;
-using VitrivrVR.Submission;
+using static VitrivrVR.Logging.Interaction;
namespace VitrivrVR.Query.Display
{
@@ -106,17 +107,7 @@ protected override void Initialize()
_enqueued++;
}
- if (ConfigManager.Config.dresEnabled)
- {
- if (queryData.Query != null)
- {
- DresClientManager.LogResults("segment", _results, queryData.Query);
- }
- else
- {
- DresClientManager.LogResults("segment", _results, queryData.StagedQuery);
- }
- }
+ LoggingController.LogQueryResults("object", _results, queryData);
}
///
@@ -156,6 +147,8 @@ private void Rotate(float degrees)
_currentStart = enabledStart;
_currentEnd = enabledEnd;
+
+ LoggingController.LogInteraction("rankedList", $"browse {Mathf.Sign(degrees)}", Browsing);
}
}
@@ -181,7 +174,7 @@ private async Task CreateResultObject(ScoredSegment result)
else
{
_objectMap[objectId] = _mediaObjectSegmentDisplays.Count;
- _mediaObjectSegmentDisplays.Add(new List {itemDisplay});
+ _mediaObjectSegmentDisplays.Add(new List { itemDisplay });
}
var index = _objectMap[objectId];
diff --git a/Assets/Scripts/VitrivrVR/Query/Display/CylinderQueryDisplay.cs b/Assets/Scripts/VitrivrVR/Query/Display/CylinderQueryDisplay.cs
index e6f9471..ddc6534 100644
--- a/Assets/Scripts/VitrivrVR/Query/Display/CylinderQueryDisplay.cs
+++ b/Assets/Scripts/VitrivrVR/Query/Display/CylinderQueryDisplay.cs
@@ -1,13 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using Vitrivr.UnityInterface.CineastApi.Model.Data;
using UnityEngine;
using UnityEngine.InputSystem;
+using Vitrivr.UnityInterface.CineastApi.Model.Data;
using VitrivrVR.Config;
+using VitrivrVR.Logging;
using VitrivrVR.Media.Display;
using VitrivrVR.Notification;
-using VitrivrVR.Submission;
+using static VitrivrVR.Logging.Interaction;
namespace VitrivrVR.Query.Display
{
@@ -27,9 +28,9 @@ public class CylinderQueryDisplay : QueryDisplay
public override int NumberOfResults => _nResults;
- private readonly List _mediaDisplays = new List();
+ private readonly List _mediaDisplays = new();
- private readonly Queue _instantiationQueue = new Queue();
+ private readonly Queue _instantiationQueue = new();
private List _results;
@@ -90,17 +91,7 @@ protected override void Initialize()
_instantiationQueue.Enqueue(segment);
}
- if (ConfigManager.Config.dresEnabled)
- {
- if (queryData.Query != null)
- {
- DresClientManager.LogResults("segment", _results, queryData.Query);
- }
- else
- {
- DresClientManager.LogResults("segment", _results, queryData.StagedQuery);
- }
- }
+ LoggingController.LogQueryResults("segment", _results, queryData);
}
///
@@ -140,7 +131,7 @@ private void Rotate(float degrees)
_currentStart = enabledStart;
_currentEnd = enabledEnd;
- DresClientManager.LogInteraction("rankedList", $"browse {Mathf.Sign(degrees)}");
+ LoggingController.LogInteraction("rankedList", $"browse {Mathf.Sign(degrees)}", Browsing);
}
}
diff --git a/Assets/Scripts/VitrivrVR/Query/Display/CylinderTemporalQueryDisplay.cs b/Assets/Scripts/VitrivrVR/Query/Display/CylinderTemporalQueryDisplay.cs
index 0deab95..aa6dc7e 100644
--- a/Assets/Scripts/VitrivrVR/Query/Display/CylinderTemporalQueryDisplay.cs
+++ b/Assets/Scripts/VitrivrVR/Query/Display/CylinderTemporalQueryDisplay.cs
@@ -5,9 +5,10 @@
using UnityEngine;
using UnityEngine.InputSystem;
using VitrivrVR.Config;
+using VitrivrVR.Logging;
using VitrivrVR.Media.Display;
using VitrivrVR.Notification;
-using VitrivrVR.Submission;
+using static VitrivrVR.Logging.Interaction;
namespace VitrivrVR.Query.Display
{
@@ -74,7 +75,7 @@ private void Update()
protected override void Initialize()
{
_results = temporalQueryData.Results.Content;
-
+
if (_results.Count == 0)
{
NotificationController.Notify("No results returned from query!");
@@ -86,10 +87,7 @@ protected override void Initialize()
_instantiationQueue.Enqueue(temporalObject);
}
- if (ConfigManager.Config.dresEnabled)
- {
- DresClientManager.LogResults("temporal", _results, temporalQueryData.Query);
- }
+ LoggingController.LogQueryResults("temporal", _results, temporalQueryData);
}
///
@@ -129,7 +127,7 @@ private void Rotate(float degrees)
_currentStart = enabledStart;
_currentEnd = enabledEnd;
- DresClientManager.LogInteraction("rankedList", $"browse {Mathf.Sign(degrees)}");
+ LoggingController.LogInteraction("rankedList", $"browse {Mathf.Sign(degrees)}", Browsing);
}
}
diff --git a/Assets/Scripts/VitrivrVR/Query/QueryController.cs b/Assets/Scripts/VitrivrVR/Query/QueryController.cs
index 95c4b4b..782850c 100644
--- a/Assets/Scripts/VitrivrVR/Query/QueryController.cs
+++ b/Assets/Scripts/VitrivrVR/Query/QueryController.cs
@@ -1,17 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using Vitrivr.UnityInterface.CineastApi;
-using Vitrivr.UnityInterface.CineastApi.Utils;
using Org.Vitrivr.CineastApi.Model;
using UnityEngine;
using UnityEngine.Events;
+using Vitrivr.UnityInterface.CineastApi;
using Vitrivr.UnityInterface.CineastApi.Model.Data;
+using Vitrivr.UnityInterface.CineastApi.Utils;
using VitrivrVR.Config;
+using VitrivrVR.Logging;
using VitrivrVR.Notification;
using VitrivrVR.Query.Display;
using VitrivrVR.Query.Term;
-using VitrivrVR.Submission;
+using static VitrivrVR.Logging.Interaction;
namespace VitrivrVR.Query
{
@@ -97,7 +98,7 @@ public void RunQuery(QueryTermManager queryTermManager)
RunQuery(stages.First());
return;
}
-
+
// With stages
RunQuery(stages);
return;
@@ -184,7 +185,7 @@ public async void RunQuery(List> stages)
timer.transform.localRotation = Quaternion.identity;
timer.SetActive(false);
}
-
+
public async void RunQuery(List>> temporalTerms)
{
var localGuid = Guid.NewGuid();
@@ -242,7 +243,7 @@ public void SelectQuery(int index)
queryFocusEvent.Invoke(CurrentQuery, index);
CurrentQuery = index;
- DresClientManager.LogInteraction("queryManagement", $"select {index}");
+ LoggingController.LogInteraction("queryManagement", $"select {index}", QueryManagement);
}
///
@@ -279,7 +280,7 @@ public void RemoveQuery(int index)
queryRemovedEvent.Invoke(index);
Destroy(queries[index].gameObject);
queries.RemoveAt(index);
- DresClientManager.LogInteraction("queryManagement", $"delete {index}");
+ LoggingController.LogInteraction("queryManagement", $"delete {index}", QueryManagement);
}
public void RemoveAllQueries()
@@ -296,7 +297,7 @@ public void ClearQuery()
SetQueryActive(CurrentQuery, false);
queryFocusEvent.Invoke(CurrentQuery, -1);
CurrentQuery = -1;
- DresClientManager.LogInteraction("queryManagement", "clear");
+ LoggingController.LogInteraction("queryManagement", "clear", QueryManagement);
}
///
@@ -342,7 +343,7 @@ private void InstantiateQueryDisplay(QueryResponse queryData)
queryFocusEvent.Invoke(CurrentQuery, queryIndex);
CurrentQuery = queryIndex;
}
-
+
private void InstantiateQueryDisplay(TemporalQueryResponse queryData)
{
if (CurrentQuery != -1)
diff --git a/Assets/Scripts/VitrivrVR/Submission/DresClientManager.cs b/Assets/Scripts/VitrivrVR/Submission/DresClientManager.cs
index 152808a..d398a05 100644
--- a/Assets/Scripts/VitrivrVR/Submission/DresClientManager.cs
+++ b/Assets/Scripts/VitrivrVR/Submission/DresClientManager.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using System.IO;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
@@ -12,46 +11,33 @@
using Vitrivr.UnityInterface.CineastApi.Model.Data;
using Vitrivr.UnityInterface.CineastApi.Model.Registries;
using VitrivrVR.Config;
+using VitrivrVR.Logging;
using VitrivrVR.Notification;
+using static Dev.Dres.ClientApi.Model.QueryEvent;
namespace VitrivrVR.Submission
{
public class DresClientManager : MonoBehaviour
{
- public static DresClient Instance;
+ private static DresClient _instance;
private static readonly List InteractionEvents = new();
private static float _interactionEventTimer;
- private static string _interactionLogPath;
- private static string _resultsLogPath;
- private static string _submissionLogPath;
-
private async void Start()
{
if (!ConfigManager.Config.dresEnabled) return;
if (ConfigManager.Config.allowInvalidCertificate)
{
- ServicePointManager.ServerCertificateValidationCallback +=
- (sender, certificate, chain, sslPolicyErrors) => true;
+ ServicePointManager.ServerCertificateValidationCallback += (_, _, _, _) => true;
+ // (sender, certificate, chain, sslPolicyErrors) => true;
}
- Instance = new DresClient();
- await Instance.Login();
- var logDir = ConfigManager.Config.logFileLocation;
- var startTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
- var username = Instance.UserDetails.Username;
- var session = Instance.UserDetails.SessionId;
- _interactionLogPath = Path.Combine(logDir, $"{startTime}_{username}_{session}_interaction.txt");
- _resultsLogPath = Path.Combine(logDir, $"{startTime}_{username}_{session}_results.txt");
- _submissionLogPath = Path.Combine(logDir, $"{startTime}_{username}_{session}_submission.txt");
- NotificationController.Notify($"Dres connected: {username}");
-
- if (ConfigManager.Config.writeLogsToFile)
- {
- Directory.CreateDirectory(ConfigManager.Config.logFileLocation);
- }
+ _instance = new DresClient();
+ await _instance.Login();
+ var username = _instance.UserDetails.Username;
+ NotificationController.Notify($"DRES connected: {username}");
}
private void Update()
@@ -78,7 +64,7 @@ public static async void SubmitResult(string mediaObjectId, int? frame = null)
try
{
- var result = await Instance.SubmitResult(mediaObjectId, frame);
+ var result = await _instance.SubmitResult(mediaObjectId, frame);
NotificationController.Notify($"Submission: {result.Submission}");
}
catch (Exception e)
@@ -86,10 +72,7 @@ public static async void SubmitResult(string mediaObjectId, int? frame = null)
NotificationController.Notify(e.Message);
}
- if (ConfigManager.Config.writeLogsToFile)
- {
- LogSubmissionToFile(mediaObjectId, frame);
- }
+ LoggingController.LogSubmission(mediaObjectId, frame);
}
///
@@ -119,33 +102,17 @@ public static async void QuickSubmitSegment(SegmentData segment)
}
}
- private static async void LogSubmissionToFile(string mediaObjectId, int? frame)
- {
- var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
- try
- {
- await using var file = new StreamWriter(_submissionLogPath, true);
- var row = $"{timestamp},{mediaObjectId}";
- if (frame != null)
- row += $",{frame}";
- await file.WriteLineAsync(row);
- }
- catch (Exception e)
- {
- NotificationController.Notify($"Error logging to file: {e.Message}");
- }
- }
-
///
- /// Logs results to the connected Dres instance.
+ /// Logs results to the connected DRES instance.
///
/// The sorting of the results display.
/// The results as list of scored segments.
/// The query that lead to these results represented as enumerable of query events.
/// Timestamp of result log.
/// Skips trying to batch fetch segment data if true.
- public static async void LogResults(string sortType, List<(ScoredSegment segment, int rank)> results,
- IEnumerable queryEvents, long timestamp, bool assumeFullyFetched = false)
+ private static async void LogResults(string sortType,
+ IReadOnlyCollection<(ScoredSegment segment, int rank)> results, IEnumerable queryEvents,
+ long timestamp, bool assumeFullyFetched = false)
{
if (!assumeFullyFetched)
{
@@ -167,7 +134,7 @@ public static async void LogResults(string sortType, List<(ScoredSegment segment
var queryEventsList = queryEvents.ToList();
try
{
- var success = await Instance.LogResults(timestamp, sortType, "top", queryResultsList, queryEventsList);
+ var success = await _instance.LogResults(timestamp, sortType, "top", queryResultsList, queryEventsList);
if (!success.Status)
{
@@ -178,31 +145,14 @@ public static async void LogResults(string sortType, List<(ScoredSegment segment
{
NotificationController.Notify(e.Message);
}
-
- if (ConfigManager.Config.writeLogsToFile)
- {
- try
- {
- using var file = new StreamWriter(_resultsLogPath, true);
- var jsonResults = string.Join(",", queryResultsList.Select(q => q.ToJson().Replace("\n", "")));
- var jsonEvents = string.Join(",", queryEventsList.Select(q => q.ToJson().Replace("\n", "")));
- var resultLog = $"{timestamp},{sortType},top,[{jsonResults}],[{jsonEvents}]";
- await file.WriteLineAsync(resultLog);
- }
- catch (Exception e)
- {
- NotificationController.NotifyError($"Error logging to file: {e.Message}", e);
- }
- }
}
- public static void LogResults(string sortType, IEnumerable results, SimilarityQuery query)
+ public static void LogResults(long timestamp, string sortType, IEnumerable results,
+ SimilarityQuery query)
{
- var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
-
var queryEvents = query.Terms.Select(term =>
{
- // Convert term type to Dres category
+ // Convert term type to DRES category
var category = TermTypeToDresCategory(term.Type);
var type = string.Join(",", term.Categories.Select(CategoryToType));
@@ -216,19 +166,19 @@ public static void LogResults(string sortType, IEnumerable result
LogResults(sortType, rankedResults, queryEvents, timestamp);
}
- public static void LogResults(string sortType, IEnumerable results, StagedSimilarityQuery query)
+ public static void LogResults(long timestamp, string sortType, IEnumerable results,
+ StagedSimilarityQuery query)
{
- var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
-
- var queryEvents = query.Stages.SelectMany(stage => stage.Terms.Select(term =>
+ var queryEvents = query.Stages.SelectMany((stage, si) => stage.Terms.Select(term =>
{
- // Convert term type to Dres category
+ // Convert term type to DRES category
var category = TermTypeToDresCategory(term.Type);
var type = string.Join(",", term.Categories.Select(CategoryToType));
var value = term.Data;
- return new QueryEvent(timestamp, category, type, value);
+ // Also provide stage index in type
+ return new QueryEvent(timestamp, category, $"{si}:{type}", value);
}));
var rankedResults = results.Select((segment, rank) => (segment, rank)).ToList();
@@ -236,15 +186,14 @@ public static void LogResults(string sortType, IEnumerable result
LogResults(sortType, rankedResults, queryEvents, timestamp);
}
- public static void LogResults(string sortType, IEnumerable results, TemporalQuery query)
+ public static void LogResults(long timestamp, string sortType, IEnumerable results,
+ TemporalQuery query)
{
- var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
-
var queryEvents = query.Queries.SelectMany(
(temporal, ti) => temporal.Stages.SelectMany(
(stage, si) => stage.Terms.Select(term =>
{
- // Convert term type to Dres category
+ // Convert term type to DRES category
var category = TermTypeToDresCategory(term.Type);
var type = string.Join(",", term.Categories.Select(CategoryToType));
@@ -274,7 +223,7 @@ private static async void LogInteraction()
// Submit to DRES
try
{
- var success = await Instance.LogQueryEvents(timestamp, InteractionEvents);
+ var success = await _instance.LogQueryEvents(timestamp, InteractionEvents);
if (!success.Status)
{
@@ -286,34 +235,14 @@ private static async void LogInteraction()
NotificationController.NotifyError($"Error logging interaction: {e.Message}", e);
}
- var events = InteractionEvents.ToArray();
InteractionEvents.Clear();
-
- // Write to file
- if (ConfigManager.Config.writeLogsToFile)
- {
- try
- {
- using var file = new StreamWriter(_interactionLogPath, true);
- foreach (var interactionEvent in events)
- {
- await file.WriteLineAsync(interactionEvent.ToJson().Replace("\n", ""));
- }
- }
- catch (Exception e)
- {
- NotificationController.NotifyError($"Error logging to file: {e.Message}", e);
- }
- }
}
- public static void LogInteraction(string type, string value,
- QueryEvent.CategoryEnum category = QueryEvent.CategoryEnum.BROWSING)
+ public static void LogInteraction(long timestamp, string type, string value, Logging.Interaction category)
{
if (!ConfigManager.Config.dresEnabled) return;
- var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
- var queryEvent = new QueryEvent(timestamp, category, type, value);
+ var queryEvent = new QueryEvent(timestamp, InteractionToDresCategory(category), type, value);
InteractionEvents.Add(queryEvent);
}
@@ -338,21 +267,37 @@ private static string CategoryToType(string category)
};
}
- private static QueryEvent.CategoryEnum TermTypeToDresCategory(QueryTerm.TypeEnum? type)
+ private static CategoryEnum TermTypeToDresCategory(QueryTerm.TypeEnum? type)
{
return type switch
{
- QueryTerm.TypeEnum.IMAGE => QueryEvent.CategoryEnum.IMAGE,
- QueryTerm.TypeEnum.AUDIO => QueryEvent.CategoryEnum.OTHER,
- QueryTerm.TypeEnum.MODEL3D => QueryEvent.CategoryEnum.OTHER,
- QueryTerm.TypeEnum.LOCATION => QueryEvent.CategoryEnum.OTHER,
- QueryTerm.TypeEnum.TIME => QueryEvent.CategoryEnum.OTHER,
- QueryTerm.TypeEnum.TEXT => QueryEvent.CategoryEnum.TEXT,
- QueryTerm.TypeEnum.TAG => QueryEvent.CategoryEnum.TEXT,
- QueryTerm.TypeEnum.SEMANTIC => QueryEvent.CategoryEnum.SKETCH,
- QueryTerm.TypeEnum.ID => QueryEvent.CategoryEnum.OTHER,
- QueryTerm.TypeEnum.BOOLEAN => QueryEvent.CategoryEnum.FILTER,
- _ => QueryEvent.CategoryEnum.OTHER
+ QueryTerm.TypeEnum.IMAGE => CategoryEnum.IMAGE,
+ QueryTerm.TypeEnum.AUDIO => CategoryEnum.OTHER,
+ QueryTerm.TypeEnum.MODEL3D => CategoryEnum.OTHER,
+ QueryTerm.TypeEnum.LOCATION => CategoryEnum.OTHER,
+ QueryTerm.TypeEnum.TIME => CategoryEnum.OTHER,
+ QueryTerm.TypeEnum.TEXT => CategoryEnum.TEXT,
+ QueryTerm.TypeEnum.TAG => CategoryEnum.TEXT,
+ QueryTerm.TypeEnum.SEMANTIC => CategoryEnum.SKETCH,
+ QueryTerm.TypeEnum.ID => CategoryEnum.OTHER,
+ QueryTerm.TypeEnum.BOOLEAN => CategoryEnum.FILTER,
+ _ => CategoryEnum.OTHER
+ };
+ }
+
+ private static CategoryEnum InteractionToDresCategory(Logging.Interaction category)
+ {
+ return category switch
+ {
+ Logging.Interaction.TextInput => CategoryEnum.TEXT,
+ Logging.Interaction.Browsing => CategoryEnum.BROWSING,
+ Logging.Interaction.ResultExpansion => CategoryEnum.BROWSING,
+ Logging.Interaction.QueryFormulation => CategoryEnum.OTHER,
+ Logging.Interaction.Query => CategoryEnum.OTHER,
+ Logging.Interaction.Filter => CategoryEnum.FILTER,
+ Logging.Interaction.Other => CategoryEnum.OTHER,
+ Logging.Interaction.QueryManagement => CategoryEnum.BROWSING,
+ _ => throw new ArgumentOutOfRangeException(nameof(category), category, null)
};
}
@@ -362,7 +307,7 @@ private static QueryEvent.CategoryEnum TermTypeToDresCategory(QueryTerm.TypeEnum
private static string RemovePrefix(string id)
{
var prefixLength = ConfigManager.Config.submissionIdPrefixLength;
- return prefixLength > 0 ? id.Substring(prefixLength) : id;
+ return prefixLength > 0 ? id[prefixLength..] : id;
}
}
}
\ No newline at end of file