Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Main merge for 1.2.5 release #243

Merged
merged 33 commits into from
Mar 5, 2024
Merged
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
994ef25
Version bump and fixed documentation url in python/README.md
SBriere Oct 27, 2023
0c65ccd
Merge branch 'main' of github.com:introlab/opentera into dev
doumdi Nov 7, 2023
e842ce1
Updated requirements
SBriere Dec 5, 2023
448aa56
Improved response time when querying project stats with participants.
SBriere Dec 7, 2023
d11c13c
Fixed issue when added participants / users / devices to a WebRTC ses…
SBriere Dec 8, 2023
a9cea8d
Refs #232. Added preloading of cameras, fixed issue on participant "w…
SBriere Dec 11, 2023
ed08788
Added "with_sites" and "with_projects" to user/online_participants AP…
SBriere Dec 11, 2023
488ad41
Add files via upload
mouhamb Jan 17, 2024
6deb66c
Added test mode for LoggingService and test API to reset database.
SBriere Jan 18, 2024
0d5288a
Removed check for valid Client-Name in UserLogin
SBriere Jan 18, 2024
3c2f9c3
Refs #237. Added Device Registration key in server settings.
SBriere Jan 23, 2024
84789ab
Updated python env to latest packages version
SBriere Jan 23, 2024
4b51d49
Refs #237. Added User API to query server settings
SBriere Jan 23, 2024
d9f1f89
Refs #237. Revised device register API.
SBriere Jan 23, 2024
f86e7bb
Fixed bug in POST in DeviceQuerySessionEvents
SBriere Jan 29, 2024
403931a
Managed TeraServerSettings redis keys when creating/updating
SBriere Feb 13, 2024
be1ff7a
Fixed bad access check in ServiceQueryProjects
SBriere Feb 15, 2024
a8f7e08
For the pull request of ServiceQueryParticipantGroups
Feb 15, 2024
64cb2a0
Update of ServiceQueryProjects
Feb 15, 2024
45f0046
Merge pull request #235 from mouhamb/mouhamb-patch-1
SBriere Mar 4, 2024
079e002
Refs #234. Merged ServiceQueryParticipantGroups
SBriere Mar 4, 2024
fa2282f
Fixes #239. Added support for "datetime.date" in to_json method
SBriere Mar 4, 2024
4710321
Refs #240. Added search by name feature for ServiceQueryParticipants
SBriere Mar 4, 2024
864a7a7
Refs #241. Added projects and sites access from ServiceQueryUserGroup…
SBriere Mar 4, 2024
b114b7d
Refs #242. Reworked camera management when unable to get a stream fro…
SBriere Mar 4, 2024
1f928ef
Updated translations, python dependencies and fixed ServiceQueryParti…
SBriere Mar 4, 2024
2acc543
Fixing auth problems with txredisapi
doumdi Mar 4, 2024
89ec64b
Added command line arguments to create default values
SBriere Mar 5, 2024
4133fde
Merge branch 'dev' of https://github.com/introlab/opentera into dev
SBriere Mar 5, 2024
5614ea0
Fix empty redis password
doumdi Mar 5, 2024
10b137e
Merge branch 'dev' of github.com:introlab/opentera into dev
doumdi Mar 5, 2024
d3fb625
Changed "create-defaults" to "create_defaults"
SBriere Mar 5, 2024
04439e8
Update conf.py
doumdi Mar 5, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 4 additions & 19 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -51,49 +51,34 @@ docs/_build/
docs/--no-check-certificate
docs/swagger.json

build-teraplus-Desktop_Qt_5_12_0_MSVC2017_64bit-Debug
*.user
build-teraserver-Desktop_Qt_5_12_0_MSVC2017_64bit-Debug
.idea
python-3.6

# Docker
docker/prod/certificates/*.pem

# Node modules
node_modules/
/teraplus/CMakeLists.txt.user.4.9-pre1
/teraserver/CMakeLists.txt.user.4.9-pre1
/teraserver/python/config/TeraServerConfig.ini~0b30c4625222f7c8696ca353a9e47d17d15d6cb5
/teraserver/python/messages/python/*
/teraserver/python/certificates/ca_cert.pem
/teraserver/python/certificates/ca_key.pem
/teraserver/python/certificates/devices/client_certificate.pem
/teraserver/python/certificates/devices/client_key.pem
/teraserver/python/certificates/site_cert.pem
/teraserver/python/certificates/site_key.pem
/teraplus/client/resources/icons/device.psd
/teraserver/python/uploads
build-teraplus-Desktop_Qt_5_13_1_MSVC2017_64bit-Debug
build-teraserver-Desktop_Qt_5_13_1_MSVC2017_64bit-Debug
build-teraplus-Desktop_Qt_5_13_1_MSVC2017_64bit-Release
build-teraserver-Desktop_Qt_5_13_2_MSVC2017_64bit-Debug
build-teraserver-Desktop_Qt_5_14_0_MSVC2017_64bit-Debug
build-teraserver-Desktop_Qt_5_14_1_MSVC2017_64bit-Debug
protobuf
teraserver/python/env/_python-3.6
build-teraserver-Desktop_Qt_5_14_2_MSVC2017_64bit-Debug
python-3.8
teraserver/python/services/BureauActif/uploads/
/teraserver/python/OpenTeraServerVersion.py
/teraserver/python/services/FileTransferService/upload
files
build-teraserver-Desktop_Qt_5_15_2_MSVC2019_64bit-Debug
python-3.10
/teraserver/easyrtc/package-lock.json
venv
joss-paper/paper.jats
joss-paper/paper.pdf
/.vscode
_python-3.10
python-3.11
build-teraserver-Desktop_Qt_6_6_1_MSVC2019_64bit-Debug
python-3.10
/teraserver/python/config/certificates
/teraserver/python/tests/*.pem
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ You are welcome to participate in this effort. Leave us comments or report [Issu

## Publication(s)

* [![DOI](https://joss.theoj.org/papers/10.21105/joss.05497/status.svg)](https://doi.org/10.21105/joss.05497) Létourneau, D., Brière , S., et al., [OpenTera: A Framework for Telehealth Applications](https://doi.org/10.21105/joss.05497), Journal of Open Source Software, vol. 8, no 91, p. 5497 (2023)
* Panchea, A.M., Létourneau, D., Brière, S. et al., [OpenTera: A microservice architecture solution for rapid prototyping of robotic solutions to COVID-19 challenges in care facilities](https://rdcu.be/cHzmf), Health Technol. 12, 583–596 (2022)

## Videos
Expand Down
2 changes: 1 addition & 1 deletion teraserver/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ endif(NOT CMAKE_BUILD_TYPE)
# Software version
SET(OPENTERA_VERSION_MAJOR "1")
SET(OPENTERA_VERSION_MINOR "2")
SET(OPENTERA_VERSION_PATCH "4")
SET(OPENTERA_VERSION_PATCH "5")

SET(OPENTERA_SERVER_VERSION OpenTera_v${OPENTERA_VERSION_MAJOR}.${OPENTERA_VERSION_MINOR}.${OPENTERA_VERSION_PATCH})

Expand Down
2 changes: 1 addition & 1 deletion teraserver/easyrtc/protected/index_users.html
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ <h5 class="modal-title" id="chronosDialogLongTitle" data-i18n="chronosDialog.tit
</select>
</div>
<div class="form-group row pr-2">
<label for="chronosTypeRadio" class="col-form-label col-4" data-i18n="chronosDialog.chrono-type">Type: </label>
<label class="col-form-label col-4" data-i18n="chronosDialog.chrono-type">Type: </label>
<div id="chronosTypeRadio" class="col col-form-label pl-0">
<input id="optChronoType1" value=1 class="mr-1" type="radio" name="optChronoType" data-i18n="chronosDialog.chrono-countdown" checked /><label class="radio-inline pr-2" for="optChronoType1">Décompte</label>
<input id="optChronoType2" value=2 class="mr-1" type="radio" name="optChronoType" data-i18n="chronosDialog.chrono-countup" /><label class="radio-inline" for="optChronoType2">Chronomètre</label>
Expand Down
3 changes: 2 additions & 1 deletion teraserver/easyrtc/static/js/tera_layout_participants.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ function updateUserLocalViewLayout(){
let remote_num = usedRemoteVideosIndexes.length;
let usedLocalVideosIndexes = getVideoStreamsIndexes(localStreams);
let local_num = usedLocalVideosIndexes.length;
//console.log(usedLocalVideosIndexes);


if (currentLargeViewId.startsWith('local') && local_num === 1){
setColWidth(largeView, 10);
Expand All @@ -112,6 +112,7 @@ function updateUserLocalViewLayout(){
}

switch(local_num){
case 0:
case 1:
selfViewRow2.hide();
break;
Expand Down
69 changes: 51 additions & 18 deletions teraserver/easyrtc/static/js/tera_medias.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,61 @@ async function fillDefaultSourceList(){
videoSources.length=0;
audioSources.length=0;

// Open a stream to ask for permissions and allow listing of full name of devices.
try{
/*await navigator.mediaDevices.getUserMedia({
audio: true,
video: {
width: {ideal: 1280, max: 1920 },
height: {ideal: 720, max: 1080 },
frameRate: {min: 15}//, ideal: 30}
}
});*/
await navigator.mediaDevices.getUserMedia({
audio: true,
video: true
});
// Get devices ids in case the first camera returned by getUserMedia isn't valid (we use usermedia here only to get
// camera names
let all_devices;
try {
all_devices = await navigator.mediaDevices.enumerateDevices();
}catch(err) {
showError("fillDefaultSourceList() - getUserMedia",
translator.translateForKey("errors.no-media-access", currentLang) + "<br><br>" +
translator.translateForKey("errors.error-msg", currentLang) +
":<br>" + err.name + " - " + err.message, true);
showError("fillDefaultSourceList() - enumerate Initial Devices", err.name + " - " + err.message, true);
throw err;
}

// Open a stream to ask for permissions and allow listing of full name of devices.
if (all_devices.length === 0){
showError(translator.translateForKey("errors.no-media-access", currentLang),
translator.translateForKey("errors.error-msg", currentLang), true);
return;
}
let current_dev_index = 0;
let ready = false;
let devices_anom = [];
all_devices.forEach(device => {
if (device.kind === "videoinput"){
devices_anom.push(device);
}
});
while(!ready){
try{
// await navigator.mediaDevices.getUserMedia({
// audio: true,
// video: {
// width: {ideal: 1280, max: 1920 },
// height: {ideal: 720, max: 1080 },
// frameRate: {min: 15}//, ideal: 30}
// }
// });
await navigator.mediaDevices.getUserMedia({
audio: true,
video: {
deviceId: devices_anom[current_dev_index].deviceId
}
}).then(function() {
ready = true;
});
}catch(err) {
current_dev_index+=1; // Will try next source
if (current_dev_index >= devices_anom.length){
// Tried every device
showError("fillDefaultSourceList() - getUserMedia",
translator.translateForKey("errors.no-media-access", currentLang) + "<br><br>" +
translator.translateForKey("errors.error-msg", currentLang) +
":<br>" + err.name + " - " + err.message, true);
throw err;
}
}
}

try {
let devices = await navigator.mediaDevices.enumerateDevices();
devices.forEach(device => {
Expand Down
76 changes: 68 additions & 8 deletions teraserver/easyrtc/static/js/tera_webrtc.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,13 @@ let localStreams = []; // {peerid, streamname, stream: MediaStream}, order is im
var connected = false;
var needToCallOtherUsers = false;

let preinitCameras = true;

function connect() {

console.log("Connecting...");
playSound("audioCalling");
if (!preinitCameras)
playSound("audioCalling");

/*var localFilter = easyrtc.buildLocalSdpFilter( {
audioRecvBitrate:20, videoRecvBitrate:30 ,videoRecvCodec:"h264"
Expand All @@ -41,11 +44,61 @@ function connect() {
//Post-connect Event listeners
//easyrtc.setOnHangup(streamDisconnected);
//easyrtc.setOnCall(newStreamStarted);
if (preinitCameras)
preloadCameras();
else{
connected = true;
updateLocalAudioVideoSource(1);
showLayout(true);
}

connected = true;
updateLocalAudioVideoSource(1);

showLayout(true);
}

// On some devices, there's a strange bug that delays access to the camera, unless we try to access it at least once...
function preloadCameras(){
navigator.mediaDevices.enumerateDevices()
.then(function(devices) {
let preload_devices = [];
devices.forEach(function(device) {
if (device.kind === "videoinput"){
if (!device.label.includes(" IR ")) { // Filter "IR" camera, since they won't work.
preload_devices.push(device);
}
}
//console.log(device.kind + ": " + device.label + " id = " + device.deviceId);
});
preloadCamera(preload_devices, 0);
})
.catch(function(err) {
console.log(err.name + ": " + err.message);
});

}

function preloadCamera(devices, current_index){
if (current_index >= devices.length || current_index < 0){
return;
}

navigator.mediaDevices.getUserMedia({video: {deviceId: { exact: devices[current_index].deviceId }},
audio: false}).then(function(stream){
console.log("Preloaded camera " + devices[current_index].label + "(" + devices[current_index].deviceId + ")");
stream.getTracks().forEach(track => track.stop());
// Did we get at least the first stream? If so, start everything!
//if (current_index === 0){
if (!connected){
playSound("audioCalling");
connected = true;
updateLocalAudioVideoSource(1);
showLayout(true);
}
preloadCamera(devices, current_index + 1);
}).catch(async function() {
console.log("Can't preload camera: " + devices[current_index].label);
/*await new Promise(resolve => setTimeout(resolve, 1000))*/
preloadCamera(devices, current_index + 1);
});
}

function muteMicro(local, index, new_state){
Expand Down Expand Up @@ -264,14 +317,15 @@ function setPrimaryView(peer_id, streamname){
setPrimaryViewIcon(primaryView.peerid, primaryView.streamName);
}

function updateLocalAudioVideoSource(streamindex){
async function updateLocalAudioVideoSource(streamindex){
if (connected === true){
let streamname = "localStream" + streamindex;
if (streamindex === 1) // Default stream = no name.
streamname = "";
if (streamindex < localStreams.length){
if (streamindex <= localStreams.length){
console.log("Updating audio/video source: " + streamname);

// Stopping previous stream
localStreams[streamindex-1].stream.getTracks().forEach(track => track.stop());
}else {
console.log("Creating audio/video source: " + streamname);
}
Expand Down Expand Up @@ -398,7 +452,13 @@ function localVideoStreamSuccess(stream){
}

function localVideoStreamError(errorCode, errorText){
showError("initMediaSource", "Error #" + errorCode + ": " + errorText, true);
if (currentConfig.currentVideoSourceIndex + 1 < videoSources.length){
console.log("initMediaSource - Unable to open current source " + videoSources[currentConfig.currentVideoSourceIndex].label + " - Trying next one..." );
currentConfig.currentVideoSourceIndex += 1;
updateLocalAudioVideoSource(1);
}else{
showError("initMediaSource", "Error #" + errorCode + ": " + errorText, true);
}
}

function forwardData(data)
Expand Down
2 changes: 1 addition & 1 deletion teraserver/python/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ External microservices can use this package as a base.
OpenTera is licensed under [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) .

# Documentation
Please visit our [WiKi documentation on GitHub](https://github.com/introlab/opentera/wiki)
Please visit our [Documentation on GitHub](https://introlab.github.io/opentera/)

# Dependencies
OpenTera is based or uses the following Open Source technologies :
Expand Down
5 changes: 3 additions & 2 deletions teraserver/python/TeraServer.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ def init_opentera_service(config: ConfigManager):
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='OpenTera Server')
parser.add_argument('--enable_tests', help='Test mode for server.', default=False)
parser.add_argument('--create_defaults', help='Create default server values (test mode)', default=False)
args = parser.parse_args()

config_man = ConfigManager()
Expand Down Expand Up @@ -147,7 +148,7 @@ def init_opentera_service(config: ConfigManager):
Globals.db_man.open(config_man.server_config['debug_mode'])

# Create minimal values, if required
Globals.db_man.create_defaults(config=config_man, test=False)
Globals.db_man.create_defaults(config=config_man, test=args.create_defaults)

except OperationalError as e:
print("Unable to connect to database - please check settings in config file!", e)
Expand All @@ -168,7 +169,7 @@ def init_opentera_service(config: ConfigManager):
init_opentera_service(config=config_man)

# Main Flask module
flask_module = FlaskModule(config_man)
flask_module = FlaskModule(config_man, test_mode=args.enable_tests)

# LOGIN MANAGER, must be initialized after Flask
#################################################
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
"""Add device register key

Revision ID: e6ee93ef205b
Revises: f41b70d6513e
Create Date: 2024-01-23 08:15:07.224075

"""
from opentera.db.models.TeraServerSettings import TeraServerSettings


# revision identifiers, used by Alembic.
revision = 'e6ee93ef205b'
down_revision = 'f41b70d6513e'
branch_labels = None
depends_on = None


def upgrade():
TeraServerSettings.set_server_setting(TeraServerSettings.ServerDeviceRegisterKey,
TeraServerSettings.generate_token_key(10))


def downgrade():
pass
Loading
Loading