From ba64929c665213e491c82189beca89d936131717 Mon Sep 17 00:00:00 2001 From: jrd Date: Thu, 23 Jul 2026 23:44:40 +0000 Subject: [PATCH] Add optional localtimezone; prefix for the recording directory (#497) Implements the design agreed in issue #497: prefixing the recording directory with "localtimezone;" (e.g. -R "localtimezone;/path/to/recordings") names recording session folders using local time instead of UTC, so they line up with the server log's local-time entries. Without the prefix, behaviour is unchanged (UTC remains the default). The prefix is parsed in CJamController::SetRecordingDir, the common path for the -R argument, the server GUI and JSON-RPC. The stored directory string keeps the prefix so it round-trips through the ini file and getRecorderStatus unchanged. Co-Authored-By: Claude Fable 5 --- docs/JSON-RPC.md | 2 +- src/main.cpp | 4 +++- src/recorder/jamcontroller.cpp | 17 +++++++++++++++-- src/recorder/jamrecorder.cpp | 8 +++++--- src/recorder/jamrecorder.h | 6 ++++-- src/serverrpc.cpp | 1 + 6 files changed, 29 insertions(+), 9 deletions(-) diff --git a/docs/JSON-RPC.md b/docs/JSON-RPC.md index e9111187f4..5eceb8c6d1 100644 --- a/docs/JSON-RPC.md +++ b/docs/JSON-RPC.md @@ -491,7 +491,7 @@ Parameters: | Name | Type | Description | | --- | --- | --- | -| params.recordingDirectory | string | The new recording directory. | +| params.recordingDirectory | string | The new recording directory. May be prefixed with "localtimezone;" to name recording session folders using local time instead of UTC. | Results: diff --git a/src/main.cpp b/src/main.cpp index a518c2e515..9a896b48a7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1173,7 +1173,9 @@ QString UsageArguments ( char** argv ) " registering with a server list hosted\n" " behind the same NAT\n" " -P, --delaypan start with delay panning enabled\n" - " -R, --recording set server recording directory; server will record when a session is active by default\n" + " -R, --recording set server recording directory; server will record when a session is active by default;\n" + " prefix the directory with \"localtimezone;\" to name session folders using local time\n" + " instead of UTC\n" " --norecord set server not to record by default when recording is configured\n" " --noraw disable raw audio\n" " -s, --server start Server\n" diff --git a/src/recorder/jamcontroller.cpp b/src/recorder/jamcontroller.cpp index 2c277fe0f3..796419fcc3 100644 --- a/src/recorder/jamcontroller.cpp +++ b/src/recorder/jamcontroller.cpp @@ -109,9 +109,22 @@ void CJamController::SetRecordingDir ( QString newRecordingDir, int iServerFrame pthJamRecorder = nullptr; } - if ( !newRecordingDir.isEmpty() ) + // An optional "localtimezone;" prefix selects local time instead of UTC for + // session folder names (#497). strRecordingDir keeps the full string below so + // the prefix round-trips unchanged through the ini file, JSON-RPC and the GUI. + const QString strLocalTimePrefix = "localtimezone;"; + bool bRecordLocalTime = false; + QString strRecordingBaseDir = newRecordingDir; + + if ( strRecordingBaseDir.startsWith ( strLocalTimePrefix ) ) { - pJamRecorder = new recorder::CJamRecorder ( newRecordingDir, iServerFrameSizeSamples ); + bRecordLocalTime = true; + strRecordingBaseDir = strRecordingBaseDir.mid ( strLocalTimePrefix.length() ); + } + + if ( !strRecordingBaseDir.isEmpty() ) + { + pJamRecorder = new recorder::CJamRecorder ( strRecordingBaseDir, iServerFrameSizeSamples, bRecordLocalTime ); strRecorderErrMsg = pJamRecorder->Init(); bRecorderInitialised = ( strRecorderErrMsg == QString() ); bEnableRecording = bRecorderInitialised && !bDisableRecording; diff --git a/src/recorder/jamrecorder.cpp b/src/recorder/jamrecorder.cpp index de99ac9b5b..7190f53082 100644 --- a/src/recorder/jamrecorder.cpp +++ b/src/recorder/jamrecorder.cpp @@ -169,11 +169,13 @@ QString CJamClient::TranslateChars ( const QString& input ) const /** * @brief CJamSession::CJamSession Construct a new jam recording session * @param recordBaseDir The recording base directory + * @param bRecordLocalTime Name the session folder using local time instead of UTC * * Each session is stored into its own subdirectory of the recording base directory. */ -CJamSession::CJamSession ( QDir recordBaseDir ) : - sessionDir ( QDir ( recordBaseDir.absoluteFilePath ( "Jam-" + QDateTime().currentDateTimeUtc().toString ( "yyyyMMdd-HHmmsszzz" ) ) ) ), +CJamSession::CJamSession ( QDir recordBaseDir, const bool bRecordLocalTime ) : + sessionDir ( QDir ( recordBaseDir.absoluteFilePath ( + "Jam-" + ( bRecordLocalTime ? QDateTime::currentDateTime() : QDateTime::currentDateTimeUtc() ).toString ( "yyyyMMdd-HHmmsszzz" ) ) ) ), currentFrame ( 0 ), chIdDisconnected ( -1 ), vecptrJamClients ( MAX_NUM_CHANNELS ), @@ -426,7 +428,7 @@ void CJamRecorder::Start() QMutexLocker mutexLocker ( &ChIdMutex ); try { - currentSession = new CJamSession ( recordBaseDir ); + currentSession = new CJamSession ( recordBaseDir, bRecordLocalTime ); isRecording = true; } catch ( const CGenErr& err ) diff --git a/src/recorder/jamrecorder.h b/src/recorder/jamrecorder.h index c564566a83..6f9fb8d437 100644 --- a/src/recorder/jamrecorder.h +++ b/src/recorder/jamrecorder.h @@ -135,7 +135,7 @@ class CJamSession : public QObject Q_OBJECT public: - CJamSession ( QDir recordBaseDir ); + CJamSession ( QDir recordBaseDir, const bool bRecordLocalTime ); virtual ~CJamSession(); @@ -176,9 +176,10 @@ class CJamRecorder : public QObject Q_OBJECT public: - CJamRecorder ( const QString strRecordingBaseDir, const int iServerFrameSizeSamples ) : + CJamRecorder ( const QString strRecordingBaseDir, const int iServerFrameSizeSamples, const bool bRecordLocalTime ) : recordBaseDir ( strRecordingBaseDir ), iServerFrameSizeSamples ( iServerFrameSizeSamples ), + bRecordLocalTime ( bRecordLocalTime ), isRecording ( false ), currentSession ( nullptr ) {} @@ -203,6 +204,7 @@ class CJamRecorder : public QObject QDir recordBaseDir; int iServerFrameSizeSamples; + bool bRecordLocalTime; bool isRecording; CJamSession* currentSession; QMutex ChIdMutex; diff --git a/src/serverrpc.cpp b/src/serverrpc.cpp index 05bb54be62..2747706a11 100644 --- a/src/serverrpc.cpp +++ b/src/serverrpc.cpp @@ -326,6 +326,7 @@ CServerRpc::CServerRpc ( CServer* pServer, CRpcServer* pRpcServer, QObject* pare /// @rpc_method jamulusserver/setRecordingDirectory /// @brief Sets the server recording directory. /// @param {string} params.recordingDirectory - The new recording directory. + /// May be prefixed with "localtimezone;" to name recording session folders using local time instead of UTC. /// @result {string} result - Always "acknowledged". /// To check if the directory was changed, call `jamulusserver/getRecorderStatus` again. pRpcServer->HandleMethod ( "jamulusserver/setRecordingDirectory", [=] ( const QJsonObject& params, QJsonObject& response ) {