From 4fa7a8d640d5c24bf82cf1992d3cb8ab992a4c95 Mon Sep 17 00:00:00 2001 From: Jijeong Lee Date: Fri, 1 Dec 2023 13:06:39 -0800 Subject: [PATCH 01/15] add modes field when creating user --- emission/core/wrapper/user.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/emission/core/wrapper/user.py b/emission/core/wrapper/user.py index 5bd84ed40..6e31cb3e1 100644 --- a/emission/core/wrapper/user.py +++ b/emission/core/wrapper/user.py @@ -127,10 +127,13 @@ def getSettings(self): @staticmethod def createProfile(uuid, ts): - initProfileObj = {'user_id': uuid, + initProfileObj = { + 'user_id': uuid, 'source':'Shankari', 'update_ts': ts, - 'mpg_array': [defaultMpg]} + 'mpg_array': [defaultMpg], + 'modes': {} + } writeResultProfile = get_profile_db().update_one( {'user_id': uuid}, {'$set': initProfileObj}, From 3074f4ea0f04a609bac5148a6c8a8c448936fb5b Mon Sep 17 00:00:00 2001 From: Jijeong Lee Date: Wed, 6 Dec 2023 19:10:28 -0800 Subject: [PATCH 02/15] create mode and get mode done --- emission/core/wrapper/user.py | 22 ++++++++++++++++++++++ emission/net/api/cfc_webapp.py | 17 +++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/emission/core/wrapper/user.py b/emission/core/wrapper/user.py index 6e31cb3e1..947dbe9cd 100644 --- a/emission/core/wrapper/user.py +++ b/emission/core/wrapper/user.py @@ -228,3 +228,25 @@ def unregister(userEmail): get_uuid_db().delete_one({'user_email': userEmail}) get_profile_db().delete_one({'user_id': uuid}) return uuid + + def getModes(self): + user = get_profile_db().find_one({'user_id': self.uuid}) + modes = user['modes'] + filteredModes = {key: value for key, value in modes.items() if value.get('isActive', False)} + sortedModes = dict(sorted(filteredModes.items(), key=lambda x: (x[1]["frequency"]), reverse=True)) + return sortedModes + + def insertMode(self, mode): + from datetime import datetime + modes = self.getModes() + if mode in modes: + modes[mode]['frequency'] = modes[mode]['frequency'] + 1 + else: + modes[mode] = { + 'createdAt': datetime.now(), + 'frequency': 1, + 'isActive': True, + } + get_profile_db().update_one({'user_id': self.uuid}, {'$set': {'modes': modes}}) + return modes + \ No newline at end of file diff --git a/emission/net/api/cfc_webapp.py b/emission/net/api/cfc_webapp.py index e585d6a25..b6eafdca4 100644 --- a/emission/net/api/cfc_webapp.py +++ b/emission/net/api/cfc_webapp.py @@ -306,6 +306,23 @@ def getUserProfile(): user = User.fromUUID(user_uuid) return user.getProfile() +@post('/mode/get') +def getUserModes(): + logging.debug("Called getUserModes") + user_uuid = getUUID(request) + user = User.fromUUID(user_uuid) + return user.getModes() + +@post('/mode/create') +def createUserMode(): + logging.debug("Called createUserMode") + new_mode = request.json['mode'] + user_uuid = getUUID(request) + user = User.fromUUID(user_uuid) + to_return = user.insertMode(new_mode) + logging.debug("Successfully created mode for user %s" % user_uuid) + return {"modes": to_return} + @post('/result/metrics/') def summarize_metrics(time_type): _fill_aggregate_backward_compat(request) From 42fb3b654e246b873ab85dcb9ce5239ba43112d5 Mon Sep 17 00:00:00 2001 From: Jijeong Lee Date: Thu, 7 Dec 2023 22:20:48 -0800 Subject: [PATCH 03/15] update modes frequency Increase new mode frequency(+1) and decrease old frequency(-1) --- emission/core/wrapper/user.py | 26 +++++++++++++++++++------- emission/net/api/cfc_webapp.py | 10 +++++----- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/emission/core/wrapper/user.py b/emission/core/wrapper/user.py index 947dbe9cd..45c491958 100644 --- a/emission/core/wrapper/user.py +++ b/emission/core/wrapper/user.py @@ -236,17 +236,29 @@ def getModes(self): sortedModes = dict(sorted(filteredModes.items(), key=lambda x: (x[1]["frequency"]), reverse=True)) return sortedModes - def insertMode(self, mode): + def updateModes(self, updated_mode): from datetime import datetime - modes = self.getModes() - if mode in modes: - modes[mode]['frequency'] = modes[mode]['frequency'] + 1 - else: - modes[mode] = { + user = get_profile_db().find_one({'user_id': self.uuid}) + modes = user['modes'] + old_mode = updated_mode['old_mode'] + new_mode = updated_mode['new_mode'] + is_new_mode_must_added = updated_mode['is_new_mode_must_added'] + + if new_mode in modes: + updated_frequency = modes[new_mode]['frequency'] + 1 + modes[new_mode]['frequency'] = updated_frequency + + if is_new_mode_must_added and not new_mode in modes: + modes[new_mode] = { 'createdAt': datetime.now(), 'frequency': 1, 'isActive': True, } + + if old_mode in modes: + updated_frequency = modes[old_mode]['frequency'] - 1 + modes[old_mode]['frequency'] = updated_frequency + get_profile_db().update_one({'user_id': self.uuid}, {'$set': {'modes': modes}}) - return modes + return self.getModes() \ No newline at end of file diff --git a/emission/net/api/cfc_webapp.py b/emission/net/api/cfc_webapp.py index b6eafdca4..944684736 100644 --- a/emission/net/api/cfc_webapp.py +++ b/emission/net/api/cfc_webapp.py @@ -313,14 +313,14 @@ def getUserModes(): user = User.fromUUID(user_uuid) return user.getModes() -@post('/mode/create') -def createUserMode(): +@post('/mode/update') +def updateUserMode(): logging.debug("Called createUserMode") - new_mode = request.json['mode'] + updated_mode = request.json['updated_mode'] user_uuid = getUUID(request) user = User.fromUUID(user_uuid) - to_return = user.insertMode(new_mode) - logging.debug("Successfully created mode for user %s" % user_uuid) + to_return = user.updateModes(updated_mode) + logging.debug("Successfully updated mode for user %s" % user_uuid) return {"modes": to_return} @post('/result/metrics/') From fdf03c2a7032685d45cd9a249356fb0b666d6023 Mon Sep 17 00:00:00 2001 From: Jijeong Lee Date: Mon, 11 Dec 2023 09:55:13 -0800 Subject: [PATCH 04/15] Change return value type to string array Reason: Javascript doesn't have sorted map data structure. We need to send the response value in sorted list. --- emission/core/wrapper/user.py | 4 ++-- emission/net/api/cfc_webapp.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/emission/core/wrapper/user.py b/emission/core/wrapper/user.py index 45c491958..1120bbac8 100644 --- a/emission/core/wrapper/user.py +++ b/emission/core/wrapper/user.py @@ -234,7 +234,7 @@ def getModes(self): modes = user['modes'] filteredModes = {key: value for key, value in modes.items() if value.get('isActive', False)} sortedModes = dict(sorted(filteredModes.items(), key=lambda x: (x[1]["frequency"]), reverse=True)) - return sortedModes + return list(sortedModes) def updateModes(self, updated_mode): from datetime import datetime @@ -243,7 +243,7 @@ def updateModes(self, updated_mode): old_mode = updated_mode['old_mode'] new_mode = updated_mode['new_mode'] is_new_mode_must_added = updated_mode['is_new_mode_must_added'] - + if new_mode in modes: updated_frequency = modes[new_mode]['frequency'] + 1 modes[new_mode]['frequency'] = updated_frequency diff --git a/emission/net/api/cfc_webapp.py b/emission/net/api/cfc_webapp.py index 944684736..575034ea9 100644 --- a/emission/net/api/cfc_webapp.py +++ b/emission/net/api/cfc_webapp.py @@ -311,17 +311,17 @@ def getUserModes(): logging.debug("Called getUserModes") user_uuid = getUUID(request) user = User.fromUUID(user_uuid) - return user.getModes() + return { 'modes' : user.getModes() } @post('/mode/update') def updateUserMode(): - logging.debug("Called createUserMode") + logging.debug("Called updateUserMode") updated_mode = request.json['updated_mode'] user_uuid = getUUID(request) user = User.fromUUID(user_uuid) to_return = user.updateModes(updated_mode) logging.debug("Successfully updated mode for user %s" % user_uuid) - return {"modes": to_return} + return { 'modes' : to_return } @post('/result/metrics/') def summarize_metrics(time_type): From 7e87462c12358c9206e8da957ba31e2014165a3f Mon Sep 17 00:00:00 2001 From: Jijeong Lee Date: Tue, 12 Dec 2023 00:34:37 -0800 Subject: [PATCH 05/15] add comments --- emission/core/wrapper/user.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/emission/core/wrapper/user.py b/emission/core/wrapper/user.py index 1120bbac8..d693e2a33 100644 --- a/emission/core/wrapper/user.py +++ b/emission/core/wrapper/user.py @@ -244,10 +244,12 @@ def updateModes(self, updated_mode): new_mode = updated_mode['new_mode'] is_new_mode_must_added = updated_mode['is_new_mode_must_added'] + # when a user changed a mode to an exsiting customized mode if new_mode in modes: updated_frequency = modes[new_mode]['frequency'] + 1 modes[new_mode]['frequency'] = updated_frequency + # when a user added a new customized mode if is_new_mode_must_added and not new_mode in modes: modes[new_mode] = { 'createdAt': datetime.now(), @@ -255,6 +257,7 @@ def updateModes(self, updated_mode): 'isActive': True, } + # when a user chaged a mode from an exsiting customized mode if old_mode in modes: updated_frequency = modes[old_mode]['frequency'] - 1 modes[old_mode]['frequency'] = updated_frequency From cfacb8f4908170ac1e959b1516b71b791391af94 Mon Sep 17 00:00:00 2001 From: Jijeong Lee Date: Fri, 15 Dec 2023 16:34:38 -0800 Subject: [PATCH 06/15] error handling when modes not exists in database --- emission/core/wrapper/user.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emission/core/wrapper/user.py b/emission/core/wrapper/user.py index d693e2a33..f4fa9e762 100644 --- a/emission/core/wrapper/user.py +++ b/emission/core/wrapper/user.py @@ -239,7 +239,7 @@ def getModes(self): def updateModes(self, updated_mode): from datetime import datetime user = get_profile_db().find_one({'user_id': self.uuid}) - modes = user['modes'] + modes = user['modes'] if 'modes' in user else {} old_mode = updated_mode['old_mode'] new_mode = updated_mode['new_mode'] is_new_mode_must_added = updated_mode['is_new_mode_must_added'] From 67c4c243c46b5dfa6749dcab26207c9f741b85f3 Mon Sep 17 00:00:00 2001 From: Jijeong Lee Date: Mon, 18 Dec 2023 17:19:50 -0800 Subject: [PATCH 07/15] add delete function, add error handling when 'modes' doesn't exist in db, change function names descriptive --- emission/core/wrapper/user.py | 27 ++++++++++++++++++++------- emission/net/api/cfc_webapp.py | 20 +++++++++++++++----- 2 files changed, 35 insertions(+), 12 deletions(-) diff --git a/emission/core/wrapper/user.py b/emission/core/wrapper/user.py index f4fa9e762..94e9572d7 100644 --- a/emission/core/wrapper/user.py +++ b/emission/core/wrapper/user.py @@ -229,14 +229,17 @@ def unregister(userEmail): get_profile_db().delete_one({'user_id': uuid}) return uuid - def getModes(self): + def getUserCustomModes(self): user = get_profile_db().find_one({'user_id': self.uuid}) - modes = user['modes'] - filteredModes = {key: value for key, value in modes.items() if value.get('isActive', False)} - sortedModes = dict(sorted(filteredModes.items(), key=lambda x: (x[1]["frequency"]), reverse=True)) - return list(sortedModes) + if 'modes' in user: + modes = user['modes'] + filteredModes = {key: value for key, value in modes.items() if value.get('isActive', False)} + sortedModes = dict(sorted(filteredModes.items(), key=lambda x: (x[1]["frequency"]), reverse=True)) + return list(sortedModes) + else: + return [] - def updateModes(self, updated_mode): + def updateUserCustomMode(self, updated_mode): from datetime import datetime user = get_profile_db().find_one({'user_id': self.uuid}) modes = user['modes'] if 'modes' in user else {} @@ -263,5 +266,15 @@ def updateModes(self, updated_mode): modes[old_mode]['frequency'] = updated_frequency get_profile_db().update_one({'user_id': self.uuid}, {'$set': {'modes': modes}}) - return self.getModes() + return self.getUserCustomModes() + + def deleteUserCustomMode(self, deleted_mode): + user = get_profile_db().find_one({'user_id': self.uuid}) + modes = user['modes'] if 'modes' in user else {} + + if deleted_mode in modes: + modes[deleted_mode]['isActive'] = False + + get_profile_db().update_one({'user_id': self.uuid}, {'$set': {'modes': modes}}) + return self.getUserCustomModes() \ No newline at end of file diff --git a/emission/net/api/cfc_webapp.py b/emission/net/api/cfc_webapp.py index 575034ea9..adaa54103 100644 --- a/emission/net/api/cfc_webapp.py +++ b/emission/net/api/cfc_webapp.py @@ -307,22 +307,32 @@ def getUserProfile(): return user.getProfile() @post('/mode/get') -def getUserModes(): - logging.debug("Called getUserModes") +def getUserCustomModes(): + logging.debug("Called getUserCustomModes") user_uuid = getUUID(request) user = User.fromUUID(user_uuid) - return { 'modes' : user.getModes() } + return { 'modes' : user.getUserCustomModes() } @post('/mode/update') -def updateUserMode(): +def updateUserCustomMode(): logging.debug("Called updateUserMode") updated_mode = request.json['updated_mode'] user_uuid = getUUID(request) user = User.fromUUID(user_uuid) - to_return = user.updateModes(updated_mode) + to_return = user.updateUserCustomMode(updated_mode) logging.debug("Successfully updated mode for user %s" % user_uuid) return { 'modes' : to_return } +@post('/mode/delete') +def deleteUserCustomMode(): + logging.debug("Called deleteUserCustomMode") + deleted_mode = request.json['deleted_mode'] + user_uuid = getUUID(request) + user = User.fromUUID(user_uuid) + to_return = user.deleteUserCustomMode(deleted_mode) + logging.debug("Successfully deleted mode for user %s" % user_uuid) + return { 'modes' : to_return } + @post('/result/metrics/') def summarize_metrics(time_type): _fill_aggregate_backward_compat(request) From b49046c29d3e9ee591c9ab00ff15cb4c85ce53b6 Mon Sep 17 00:00:00 2001 From: Jijeong Lee Date: Tue, 19 Dec 2023 17:09:07 -0800 Subject: [PATCH 08/15] done with unit tests --- .../wrapperTests/TestUserCustomMode.py | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 emission/tests/coreTests/wrapperTests/TestUserCustomMode.py diff --git a/emission/tests/coreTests/wrapperTests/TestUserCustomMode.py b/emission/tests/coreTests/wrapperTests/TestUserCustomMode.py new file mode 100644 index 000000000..de7ed0078 --- /dev/null +++ b/emission/tests/coreTests/wrapperTests/TestUserCustomMode.py @@ -0,0 +1,55 @@ +from __future__ import division +from __future__ import unicode_literals +from __future__ import print_function +from __future__ import absolute_import +# Standard imports +from future import standard_library +standard_library.install_aliases() +from builtins import * +import unittest + +# Our imports +from emission.core.wrapper.user import User +import emission.tests.common as etc +import emission.core.get_database as edb + +import emission.tests.common as etc + +class TestUserCustomMode(unittest.TestCase): + + def setUp(self): + etc.dropAllCollections(edb._get_current_db()) + self.user = User.register('fake@fake.com') + + def testinitialGetUserCustomModes(self): + self.assertListEqual(self.user.getUserCustomModes(), []) + + def testInsertUserCustomMode(self): + updated_mode = { + 'old_mode' : '', + 'new_mode' : 'test1', + 'is_new_mode_must_added': True + } + mode = self.user.updateUserCustomMode(updated_mode) + self.assertListEqual(mode, ['test1']) + + def testUpdateUserCustomMode(self): + self.testInsertUserCustomMode() + updated_mode = { + 'old_mode' : 'test1', + 'new_mode' : 'test2', + 'is_new_mode_must_added': True + } + mode = self.user.updateUserCustomMode(updated_mode) + self.assertListEqual(mode, ['test2', 'test1']) + + def testDeleteUserCustomMode(self): + self.testInsertUserCustomMode() + mode = self.user.deleteUserCustomMode('test1') + self.assertListEqual(mode, []) + + +if __name__ == '__main__': + etc.configLogging() + unittest.main() + From 29a4222e2ae8e3c9e34fd0a28d5c8dcc9ed47c06 Mon Sep 17 00:00:00 2001 From: Jijeong Lee Date: Tue, 19 Dec 2023 17:33:17 -0800 Subject: [PATCH 09/15] drop all collections when tear down --- emission/tests/coreTests/wrapperTests/TestUserCustomMode.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/emission/tests/coreTests/wrapperTests/TestUserCustomMode.py b/emission/tests/coreTests/wrapperTests/TestUserCustomMode.py index de7ed0078..53d821bef 100644 --- a/emission/tests/coreTests/wrapperTests/TestUserCustomMode.py +++ b/emission/tests/coreTests/wrapperTests/TestUserCustomMode.py @@ -18,7 +18,6 @@ class TestUserCustomMode(unittest.TestCase): def setUp(self): - etc.dropAllCollections(edb._get_current_db()) self.user = User.register('fake@fake.com') def testinitialGetUserCustomModes(self): @@ -48,6 +47,9 @@ def testDeleteUserCustomMode(self): mode = self.user.deleteUserCustomMode('test1') self.assertListEqual(mode, []) + def tearDown(self): + etc.dropAllCollections(edb._get_current_db()) + if __name__ == '__main__': etc.configLogging() From 5c8f20c81b408bfcacd26f4c2327bee288168afa Mon Sep 17 00:00:00 2001 From: Jijeong Lee Date: Fri, 29 Dec 2023 13:34:48 -0800 Subject: [PATCH 10/15] Add insert user custom mode function --- emission/core/wrapper/user.py | 12 ++++++++++++ emission/net/api/cfc_webapp.py | 10 ++++++++++ 2 files changed, 22 insertions(+) diff --git a/emission/core/wrapper/user.py b/emission/core/wrapper/user.py index 94e9572d7..22dbc0f48 100644 --- a/emission/core/wrapper/user.py +++ b/emission/core/wrapper/user.py @@ -238,6 +238,18 @@ def getUserCustomModes(self): return list(sortedModes) else: return [] + + def insertUserCustomMode(self, new_mode): + from datetime import datetime + user = get_profile_db().find_one({'user_id': self.uuid}) + modes = user['modes'] if 'modes' in user else {} + modes[new_mode] = { + 'createdAt': datetime.now(), + 'frequency': 0, + 'isActive': True, + } + get_profile_db().update_one({'user_id': self.uuid}, {'$set': {'modes': modes}}) + return self.getUserCustomModes() def updateUserCustomMode(self, updated_mode): from datetime import datetime diff --git a/emission/net/api/cfc_webapp.py b/emission/net/api/cfc_webapp.py index adaa54103..7dbbdee11 100644 --- a/emission/net/api/cfc_webapp.py +++ b/emission/net/api/cfc_webapp.py @@ -313,6 +313,16 @@ def getUserCustomModes(): user = User.fromUUID(user_uuid) return { 'modes' : user.getUserCustomModes() } +@post('/mode/insert') +def insertUserCustomModes(): + logging.debug("Called insertUserMode") + new_mode = request.json['new_mode'] + user_uuid = getUUID(request) + user = User.fromUUID(user_uuid) + to_return = user.insertUserCustomMode(new_mode) + logging.debug("Successfully inserted mode for user %s" % user_uuid) + return { 'modes' : to_return } + @post('/mode/update') def updateUserCustomMode(): logging.debug("Called updateUserMode") From 5308550b9303ac64bf14e1e4f99f65aaec1034eb Mon Sep 17 00:00:00 2001 From: Jijeong Lee Date: Fri, 5 Jan 2024 12:33:22 -0800 Subject: [PATCH 11/15] Modify the mode functions to encompass all types of labels (purpose, replaced_mode...) --- emission/core/wrapper/user.py | 80 ++++++++++++++++++---------------- emission/net/api/cfc_webapp.py | 60 +++++++++++++------------ 2 files changed, 75 insertions(+), 65 deletions(-) diff --git a/emission/core/wrapper/user.py b/emission/core/wrapper/user.py index 22dbc0f48..8e0bc1d65 100644 --- a/emission/core/wrapper/user.py +++ b/emission/core/wrapper/user.py @@ -132,7 +132,9 @@ def createProfile(uuid, ts): 'source':'Shankari', 'update_ts': ts, 'mpg_array': [defaultMpg], - 'modes': {} + 'mode': {}, + 'purpose': {}, + 'replaced_mode' : {} } writeResultProfile = get_profile_db().update_one( {'user_id': uuid}, @@ -229,64 +231,68 @@ def unregister(userEmail): get_profile_db().delete_one({'user_id': uuid}) return uuid - def getUserCustomModes(self): + def getUserCustomLabel(self, key): user = get_profile_db().find_one({'user_id': self.uuid}) - if 'modes' in user: - modes = user['modes'] - filteredModes = {key: value for key, value in modes.items() if value.get('isActive', False)} - sortedModes = dict(sorted(filteredModes.items(), key=lambda x: (x[1]["frequency"]), reverse=True)) - return list(sortedModes) + if key in user: + labels = user[key] + filteredLabels = {key: value for key, value in labels.items() if value.get('isActive', False)} + sortedLabels = dict(sorted(filteredLabels.items(), key=lambda x: (x[1]["frequency"]), reverse=True)) + return list(sortedLabels) else: return [] - def insertUserCustomMode(self, new_mode): + def insertUserCustomLabel(self, inserted_label): from datetime import datetime user = get_profile_db().find_one({'user_id': self.uuid}) - modes = user['modes'] if 'modes' in user else {} - modes[new_mode] = { + key = inserted_label['key'] + label = inserted_label['label'] + items = user[key] if key in user else {} + items[label] = { 'createdAt': datetime.now(), 'frequency': 0, 'isActive': True, } - get_profile_db().update_one({'user_id': self.uuid}, {'$set': {'modes': modes}}) - return self.getUserCustomModes() + get_profile_db().update_one({'user_id': self.uuid}, {'$set': {key: items}}) + return self.getUserCustomLabel(key) - def updateUserCustomMode(self, updated_mode): + def updateUserCustomLabel(self, updated_label): from datetime import datetime user = get_profile_db().find_one({'user_id': self.uuid}) - modes = user['modes'] if 'modes' in user else {} - old_mode = updated_mode['old_mode'] - new_mode = updated_mode['new_mode'] - is_new_mode_must_added = updated_mode['is_new_mode_must_added'] - - # when a user changed a mode to an exsiting customized mode - if new_mode in modes: - updated_frequency = modes[new_mode]['frequency'] + 1 - modes[new_mode]['frequency'] = updated_frequency + key = updated_label['key'] + items = user[key] if key in user else {} + old_label = updated_label['old_label'] + new_label = updated_label['new_label'] + is_new_label_must_added = updated_label['is_new_label_must_added'] + # when a user changed a label to an exsiting customized label + if new_label in items: + updated_frequency = items[new_label]['frequency'] + 1 + items[new_label]['frequency'] = updated_frequency - # when a user added a new customized mode - if is_new_mode_must_added and not new_mode in modes: - modes[new_mode] = { + # when a user added a new customized label + if is_new_label_must_added and not new_label in items: + items[new_label] = { 'createdAt': datetime.now(), 'frequency': 1, 'isActive': True, } - # when a user chaged a mode from an exsiting customized mode - if old_mode in modes: - updated_frequency = modes[old_mode]['frequency'] - 1 - modes[old_mode]['frequency'] = updated_frequency + # when a user chaged a label from an exsiting customized label + if old_label in items: + updated_frequency = items[old_label]['frequency'] - 1 + items[old_label]['frequency'] = updated_frequency - get_profile_db().update_one({'user_id': self.uuid}, {'$set': {'modes': modes}}) - return self.getUserCustomModes() + get_profile_db().update_one({'user_id': self.uuid}, {'$set': {key: items}}) + return self.getUserCustomLabel(key) - def deleteUserCustomMode(self, deleted_mode): + def deleteUserCustomLabel(self, deleted_label): user = get_profile_db().find_one({'user_id': self.uuid}) - modes = user['modes'] if 'modes' in user else {} + key = deleted_label['key'] + label = deleted_label['label'] + items = user[key] if key in user else {} - if deleted_mode in modes: - modes[deleted_mode]['isActive'] = False + if label in items: + items[label]['isActive'] = False - get_profile_db().update_one({'user_id': self.uuid}, {'$set': {'modes': modes}}) - return self.getUserCustomModes() + get_profile_db().update_one({'user_id': self.uuid}, {'$set': {key: items}}) + return self.getUserCustomLabel(key) \ No newline at end of file diff --git a/emission/net/api/cfc_webapp.py b/emission/net/api/cfc_webapp.py index 7dbbdee11..0abcb7ee3 100644 --- a/emission/net/api/cfc_webapp.py +++ b/emission/net/api/cfc_webapp.py @@ -306,42 +306,46 @@ def getUserProfile(): user = User.fromUUID(user_uuid) return user.getProfile() -@post('/mode/get') -def getUserCustomModes(): - logging.debug("Called getUserCustomModes") +@post('/customlabel/get') +def getUserCustomLabels(): + logging.debug("Called getUserCustomLabels") + keys = request.json['keys'] user_uuid = getUUID(request) user = User.fromUUID(user_uuid) - return { 'modes' : user.getUserCustomModes() } - -@post('/mode/insert') -def insertUserCustomModes(): - logging.debug("Called insertUserMode") - new_mode = request.json['new_mode'] + to_return = {} + for key in keys: + to_return[key] = user.getUserCustomLabel(key) + return to_return + +@post('/customlabel/insert') +def insertUserCustomLabel(): + logging.debug("Called insertUserCustomLabel") + inserted_label = request.json['inserted_label'] user_uuid = getUUID(request) user = User.fromUUID(user_uuid) - to_return = user.insertUserCustomMode(new_mode) - logging.debug("Successfully inserted mode for user %s" % user_uuid) - return { 'modes' : to_return } - -@post('/mode/update') -def updateUserCustomMode(): - logging.debug("Called updateUserMode") - updated_mode = request.json['updated_mode'] + to_return = user.insertUserCustomLabel(inserted_label) + logging.debug("Successfully inserted label for user %s" % user_uuid) + return { 'label' : to_return } + +@post('/customlabel/update') +def updateUserCustomLabel(): + logging.debug("Called updateUserCustomLabel") + updated_label = request.json['updated_label'] user_uuid = getUUID(request) user = User.fromUUID(user_uuid) - to_return = user.updateUserCustomMode(updated_mode) - logging.debug("Successfully updated mode for user %s" % user_uuid) - return { 'modes' : to_return } - -@post('/mode/delete') -def deleteUserCustomMode(): - logging.debug("Called deleteUserCustomMode") - deleted_mode = request.json['deleted_mode'] + to_return = user.updateUserCustomLabel(updated_label) + logging.debug("Successfully updated label label for user %s" % user_uuid) + return { 'label' : to_return } + +@post('/customlabel/delete') +def deleteUserCustomLabel(): + logging.debug("Called deleteUserCustomLabel") + deleted_label = request.json['deleted_label'] user_uuid = getUUID(request) user = User.fromUUID(user_uuid) - to_return = user.deleteUserCustomMode(deleted_mode) - logging.debug("Successfully deleted mode for user %s" % user_uuid) - return { 'modes' : to_return } + to_return = user.deleteUserCustomLabel(deleted_label) + logging.debug("Successfully deleted label for user %s" % user_uuid) + return { 'label' : to_return } @post('/result/metrics/') def summarize_metrics(time_type): From 3db594cad9ca56439439cad7fdded406f00db6a5 Mon Sep 17 00:00:00 2001 From: Jijeong Lee Date: Mon, 8 Jan 2024 12:44:36 -0800 Subject: [PATCH 12/15] update UsercustomLabel test cases (mode & purpose) --- .../wrapperTests/TestUserCustomLabel.py | 86 +++++++++++++++++++ .../wrapperTests/TestUserCustomMode.py | 57 ------------ 2 files changed, 86 insertions(+), 57 deletions(-) create mode 100644 emission/tests/coreTests/wrapperTests/TestUserCustomLabel.py delete mode 100644 emission/tests/coreTests/wrapperTests/TestUserCustomMode.py diff --git a/emission/tests/coreTests/wrapperTests/TestUserCustomLabel.py b/emission/tests/coreTests/wrapperTests/TestUserCustomLabel.py new file mode 100644 index 000000000..a0aa30842 --- /dev/null +++ b/emission/tests/coreTests/wrapperTests/TestUserCustomLabel.py @@ -0,0 +1,86 @@ +from __future__ import division +from __future__ import unicode_literals +from __future__ import print_function +from __future__ import absolute_import +# Standard imports +from future import standard_library +standard_library.install_aliases() +from builtins import * +import unittest + +# Our imports +from emission.core.wrapper.user import User +import emission.tests.common as etc +import emission.core.get_database as edb + +import emission.tests.common as etc + +class TestUserCustomMode(unittest.TestCase): + + def setUp(self): + self.user = User.register('fake@fake.com') + + def testInitialGetUserCustomLabels(self): + self.assertListEqual(self.user.getUserCustomLabel('mode'), []) + self.assertListEqual(self.user.getUserCustomLabel('purpose'), []) + + def testInsertCustomLabel(self): + inserted_mode = { + 'key' : 'mode', + 'label' : 'mode1', + } + mode = self.user.insertUserCustomLabel(inserted_mode) + self.assertListEqual(mode, ['mode1']) + + inserted_purpose = { + 'key' : 'purpose', + 'label' : 'purpose1', + } + purpose = self.user.insertUserCustomLabel(inserted_purpose) + self.assertListEqual(purpose, ['purpose1']) + + def tesUpdateUserCustomLabel(self): + self.testInsertCustomLabel() + updated_mode = { + 'key' : 'mode', + 'old_label' : '', + 'new_label' : 'mode2', + 'is_new_label_must_added': True + } + mode = self.user.updateUserCustomLabel(updated_mode) + self.assertListEqual(mode, ['mode2', 'mode1']) + + updated_purpose = { + 'key' : 'purpose', + 'old_label' : '', + 'new_label' : 'purpose2', + 'is_new_label_must_added': True + } + purpose = self.user.updateUserCustomLabel(updated_purpose) + self.assertListEqual(purpose, ['purpose2', 'purpose1']) + + def testDeleteUserCustomMode(self): + self.tesUpdateUserCustomLabel() + deleted_mode = { + 'key' : 'mode', + 'label' : 'mode2', + } + mode = self.user.deleteUserCustomLabel(deleted_mode) + + self.assertListEqual(mode, ['mode1']) + + deleted_purpose = { + 'key' : 'purpose', + 'label' : 'purpose2', + } + purpose = self.user.deleteUserCustomLabel(deleted_purpose) + self.assertListEqual(purpose, ['purpose1']) + + def tearDown(self): + etc.dropAllCollections(edb._get_current_db()) + + +if __name__ == '__main__': + etc.configLogging() + unittest.main() + diff --git a/emission/tests/coreTests/wrapperTests/TestUserCustomMode.py b/emission/tests/coreTests/wrapperTests/TestUserCustomMode.py deleted file mode 100644 index 53d821bef..000000000 --- a/emission/tests/coreTests/wrapperTests/TestUserCustomMode.py +++ /dev/null @@ -1,57 +0,0 @@ -from __future__ import division -from __future__ import unicode_literals -from __future__ import print_function -from __future__ import absolute_import -# Standard imports -from future import standard_library -standard_library.install_aliases() -from builtins import * -import unittest - -# Our imports -from emission.core.wrapper.user import User -import emission.tests.common as etc -import emission.core.get_database as edb - -import emission.tests.common as etc - -class TestUserCustomMode(unittest.TestCase): - - def setUp(self): - self.user = User.register('fake@fake.com') - - def testinitialGetUserCustomModes(self): - self.assertListEqual(self.user.getUserCustomModes(), []) - - def testInsertUserCustomMode(self): - updated_mode = { - 'old_mode' : '', - 'new_mode' : 'test1', - 'is_new_mode_must_added': True - } - mode = self.user.updateUserCustomMode(updated_mode) - self.assertListEqual(mode, ['test1']) - - def testUpdateUserCustomMode(self): - self.testInsertUserCustomMode() - updated_mode = { - 'old_mode' : 'test1', - 'new_mode' : 'test2', - 'is_new_mode_must_added': True - } - mode = self.user.updateUserCustomMode(updated_mode) - self.assertListEqual(mode, ['test2', 'test1']) - - def testDeleteUserCustomMode(self): - self.testInsertUserCustomMode() - mode = self.user.deleteUserCustomMode('test1') - self.assertListEqual(mode, []) - - def tearDown(self): - etc.dropAllCollections(edb._get_current_db()) - - -if __name__ == '__main__': - etc.configLogging() - unittest.main() - From 41fea1305b1a8129f6237d36c067dd6b23df2679 Mon Sep 17 00:00:00 2001 From: Jijeong Lee Date: Tue, 9 Jan 2024 12:05:25 -0800 Subject: [PATCH 13/15] handling an edge case when a label already exists in database --- emission/core/wrapper/user.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/emission/core/wrapper/user.py b/emission/core/wrapper/user.py index 8e0bc1d65..acb1d2e48 100644 --- a/emission/core/wrapper/user.py +++ b/emission/core/wrapper/user.py @@ -247,11 +247,17 @@ def insertUserCustomLabel(self, inserted_label): key = inserted_label['key'] label = inserted_label['label'] items = user[key] if key in user else {} - items[label] = { - 'createdAt': datetime.now(), - 'frequency': 0, - 'isActive': True, - } + + # if label exists in database, chage it as 'active' label + if label in items: + items[label]['isActive'] = True + else: + items[label] = { + 'createdAt': datetime.now(), + 'frequency': 0, + 'isActive': True, + } + get_profile_db().update_one({'user_id': self.uuid}, {'$set': {key: items}}) return self.getUserCustomLabel(key) From cea1baea50aee84fe9ce9f56dcbcba024a4d0e1a Mon Sep 17 00:00:00 2001 From: Jijeong Lee Date: Thu, 11 Jan 2024 13:51:10 -0800 Subject: [PATCH 14/15] combine mode and replaced_mode --- emission/core/wrapper/user.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/emission/core/wrapper/user.py b/emission/core/wrapper/user.py index acb1d2e48..9cc0d9646 100644 --- a/emission/core/wrapper/user.py +++ b/emission/core/wrapper/user.py @@ -133,8 +133,7 @@ def createProfile(uuid, ts): 'update_ts': ts, 'mpg_array': [defaultMpg], 'mode': {}, - 'purpose': {}, - 'replaced_mode' : {} + 'purpose': {} } writeResultProfile = get_profile_db().update_one( {'user_id': uuid}, From 7d3f313d2b7f228e678b3d4ccff0d11595642df7 Mon Sep 17 00:00:00 2001 From: Jijeong Lee Date: Thu, 11 Jan 2024 14:38:30 -0800 Subject: [PATCH 15/15] make the label active when updating it, in the case if it is inactive --- emission/core/wrapper/user.py | 1 + 1 file changed, 1 insertion(+) diff --git a/emission/core/wrapper/user.py b/emission/core/wrapper/user.py index 9cc0d9646..d8f2a2b5a 100644 --- a/emission/core/wrapper/user.py +++ b/emission/core/wrapper/user.py @@ -272,6 +272,7 @@ def updateUserCustomLabel(self, updated_label): if new_label in items: updated_frequency = items[new_label]['frequency'] + 1 items[new_label]['frequency'] = updated_frequency + items[new_label]['isActive'] = True # when a user added a new customized label if is_new_label_must_added and not new_label in items: