From 551cfba0186daddadaec97dd96af17a04dc5b743 Mon Sep 17 00:00:00 2001 From: Anton Yarmolenko Date: Fri, 19 Jan 2024 17:06:57 +0100 Subject: [PATCH 01/10] chore: add default_config/config_settings.yaml to ignore --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 8a80e27f8..a339ffb50 100644 --- a/.gitignore +++ b/.gitignore @@ -115,4 +115,5 @@ vendor/ venv/ Podfile.lock config_settings.yaml -default_config/ \ No newline at end of file +default_config/ +default_config/config_settings.yaml From 9391e8ff1c5561097d591a07f5eced721287d8d4 Mon Sep 17 00:00:00 2001 From: Anton Yarmolenko Date: Fri, 19 Jan 2024 18:30:53 +0100 Subject: [PATCH 02/10] chore: added FF for skip page in What's New --- .../Configuration/Config/UIComponentsConfig.swift | 5 ++++- OpenEdX/RouteController.swift | 2 +- OpenEdX/Router.swift | 2 +- WhatsNew/WhatsNew/Data/WhatsNewModel.swift | 7 ++----- WhatsNew/WhatsNew/Presentation/WhatsNewView.swift | 2 +- .../WhatsNew/Presentation/WhatsNewViewModel.swift | 11 +++++++++-- .../WhatsNewTests/Presentation/WhatsNewTests.swift | 8 +++++--- 7 files changed, 23 insertions(+), 14 deletions(-) diff --git a/Core/Core/Configuration/Config/UIComponentsConfig.swift b/Core/Core/Configuration/Config/UIComponentsConfig.swift index 4dd4f8be6..027f7d639 100644 --- a/Core/Core/Configuration/Config/UIComponentsConfig.swift +++ b/Core/Core/Configuration/Config/UIComponentsConfig.swift @@ -7,21 +7,24 @@ import Foundation -private enum Keys: String { +private enum Keys: String, RawStringExtractable { case courseNestedListEnabled = "COURSE_NESTED_LIST_ENABLED" case courseTopTabBarEnabled = "COURSE_TOP_TAB_BAR_ENABLED" case courseBannerEnabled = "COURSE_BANNER_ENABLED" + case whatsNewImageOrTitlePageSkip = "WHATS_NEW_IMAGE_OR_TITLE_TO_SKIP_PAGE" } public class UIComponentsConfig: NSObject { public var courseNestedListEnabled: Bool = false public var courseBannerEnabled: Bool public var courseTopTabBarEnabled: Bool + public let whatsNewImageOrTitlePageSkip: String? init(dictionary: [String: Any]) { courseNestedListEnabled = dictionary[Keys.courseNestedListEnabled.rawValue] as? Bool ?? false courseBannerEnabled = dictionary[Keys.courseBannerEnabled.rawValue] as? Bool ?? false courseTopTabBarEnabled = dictionary[Keys.courseTopTabBarEnabled.rawValue] as? Bool ?? false + whatsNewImageOrTitlePageSkip = dictionary[Keys.whatsNewImageOrTitlePageSkip] as? String super.init() } } diff --git a/OpenEdX/RouteController.swift b/OpenEdX/RouteController.swift index 70bae693c..006c26262 100644 --- a/OpenEdX/RouteController.swift +++ b/OpenEdX/RouteController.swift @@ -65,7 +65,7 @@ class RouteController: UIViewController { var storage = Container.shared.resolve(WhatsNewStorage.self)! let config = Container.shared.resolve(ConfigProtocol.self)! - let viewModel = WhatsNewViewModel(storage: storage) + let viewModel = WhatsNewViewModel(storage: storage, config: config) let shouldShowWhatsNew = viewModel.shouldShowWhatsNew() if shouldShowWhatsNew && config.features.whatNewEnabled { diff --git a/OpenEdX/Router.swift b/OpenEdX/Router.swift index 9819bf335..fc41ac63a 100644 --- a/OpenEdX/Router.swift +++ b/OpenEdX/Router.swift @@ -63,7 +63,7 @@ public class Router: AuthorizationRouter, var storage = Container.shared.resolve(WhatsNewStorage.self)! let config = Container.shared.resolve(ConfigProtocol.self)! - let viewModel = WhatsNewViewModel(storage: storage, sourceScreen: sourceScreen) + let viewModel = WhatsNewViewModel(storage: storage, sourceScreen: sourceScreen, config: config) let whatsNew = WhatsNewView(router: Container.shared.resolve(WhatsNewRouter.self)!, viewModel: viewModel) let shouldShowWhatsNew = viewModel.shouldShowWhatsNew() diff --git a/WhatsNew/WhatsNew/Data/WhatsNewModel.swift b/WhatsNew/WhatsNew/Data/WhatsNewModel.swift index 48302fb62..167cd3ee2 100644 --- a/WhatsNew/WhatsNew/Data/WhatsNewModel.swift +++ b/WhatsNew/WhatsNew/Data/WhatsNewModel.swift @@ -39,10 +39,8 @@ extension WhatsNewModel { let v1 = version1.split(separator: ".").compactMap { Int($0) } let v2 = version2.split(separator: ".").compactMap { Int($0) } - for (a, b) in zip(v1, v2) { - if a != b { - return a < b ? .orderedAscending : .orderedDescending - } + for (a, b) in zip(v1, v2) where a != b { + return a < b ? .orderedAscending : .orderedDescending } return v1.count < v2.count ? .orderedAscending : (v1.count > v2.count ? .orderedDescending : .orderedSame) @@ -55,7 +53,6 @@ extension WhatsNewModel { return latestVersion } - var domain: [WhatsNewPage] { guard let latestVersion = findLatestVersion(self.map { $0.version }) else { return [] } return self.first(where: { $0.version == latestVersion })?.messages.map { diff --git a/WhatsNew/WhatsNew/Presentation/WhatsNewView.swift b/WhatsNew/WhatsNew/Presentation/WhatsNewView.swift index cbc1cb42f..8b3798a7e 100644 --- a/WhatsNew/WhatsNew/Presentation/WhatsNewView.swift +++ b/WhatsNew/WhatsNew/Presentation/WhatsNewView.swift @@ -153,7 +153,7 @@ struct WhatsNewView_Previews: PreviewProvider { static var previews: some View { WhatsNewView( router: WhatsNewRouterMock(), - viewModel: WhatsNewViewModel(storage: WhatsNewStorageMock()) + viewModel: WhatsNewViewModel(storage: WhatsNewStorageMock(), config: ConfigMock()) ) .loadFonts() } diff --git a/WhatsNew/WhatsNew/Presentation/WhatsNewViewModel.swift b/WhatsNew/WhatsNew/Presentation/WhatsNewViewModel.swift index 12eb34b78..f6097bfac 100644 --- a/WhatsNew/WhatsNew/Presentation/WhatsNewViewModel.swift +++ b/WhatsNew/WhatsNew/Presentation/WhatsNewViewModel.swift @@ -14,10 +14,12 @@ public class WhatsNewViewModel: ObservableObject { @Published var newItems: [WhatsNewPage] = [] private let storage: WhatsNewStorage var sourceScreen: LogistrationSourceScreen + private let config: ConfigProtocol - public init(storage: WhatsNewStorage, sourceScreen: LogistrationSourceScreen = .default) { + public init(storage: WhatsNewStorage, sourceScreen: LogistrationSourceScreen = .default, config: ConfigProtocol) { self.storage = storage self.sourceScreen = sourceScreen + self.config = config newItems = loadWhatsNew() } @@ -54,7 +56,12 @@ public class WhatsNewViewModel: ObservableObject { func loadWhatsNew() -> [WhatsNewPage] { guard let domain = loadWhatsNewModel()?.domain else { return [] } - return domain + if let imageOrTitle = config.uiComponents.whatsNewImageOrTitlePageSkip, + !imageOrTitle.isEmpty { + return domain.filter { $0.image != imageOrTitle && $0.title != imageOrTitle } + } else { + return domain + } } private func loadWhatsNewModel() -> WhatsNewModel? { diff --git a/WhatsNew/WhatsNewTests/Presentation/WhatsNewTests.swift b/WhatsNew/WhatsNewTests/Presentation/WhatsNewTests.swift index 4f43a51dd..dd4a83b21 100644 --- a/WhatsNew/WhatsNewTests/Presentation/WhatsNewTests.swift +++ b/WhatsNew/WhatsNewTests/Presentation/WhatsNewTests.swift @@ -6,21 +6,23 @@ // import XCTest +import Core @testable import WhatsNew final class WhatsNewTests: XCTestCase { func testGetVersion() throws { - let viewModel = WhatsNewViewModel(storage: WhatsNewStorageMock()) + let config = ConfigMock() + let viewModel = WhatsNewViewModel(storage: WhatsNewStorageMock(), config: config) let version = viewModel.getVersion() XCTAssertNotNil(version) XCTAssertTrue(version == "1.0") } func testshouldShowWhatsNew() throws { - let viewModel = WhatsNewViewModel(storage: WhatsNewStorageMock()) + let config = ConfigMock() + let viewModel = WhatsNewViewModel(storage: WhatsNewStorageMock(), config: config) let version = viewModel.getVersion() - XCTAssertNotNil(version) XCTAssertTrue(viewModel.shouldShowWhatsNew()) } From 12ebdfa05c3d457ba1cebe3d08b04cce39f92a6b Mon Sep 17 00:00:00 2001 From: Anton Yarmolenko Date: Fri, 19 Jan 2024 20:26:08 +0100 Subject: [PATCH 03/10] chore: merge dictionaries from ios and shared yaml files instead of update --- config_script/process_config.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/config_script/process_config.py b/config_script/process_config.py index dd24319b0..36340bfc3 100644 --- a/config_script/process_config.py +++ b/config_script/process_config.py @@ -68,7 +68,7 @@ def load_config(self): with open(path, 'r') as file: dict = yaml.safe_load(file) if dict is not None: - properties.update(dict) + properties = merge_dicts(properties, dict) except FileNotFoundError: print(f"{path} not found. Skipping.") @@ -82,7 +82,7 @@ def yaml_to_plist(self): with open(path, 'r') as file: yaml_data = yaml.safe_load(file) if yaml_data is not None: - plist_data.update(yaml_data) + plist_data = merge_dicts(plist_data, yaml_data) except FileNotFoundError: print(f"{path} not found. Skipping.") except yaml.YAMLError as e: @@ -117,7 +117,14 @@ def get_info_plist_contents(self, plist_path): except Exception as e: print(f"Error reading plist file: {e}") return None - + +def merge_dicts(d1, d2): + for k, v in d2.items(): + if k in d1: + d1[k] = dict(v,**d1[k]) + else: + d1[k] = v + return d1 class ConfigurationManager: def __init__(self, plist_manager): From fc83a4e72bf5840040c0f9e308f801561d65f59d Mon Sep 17 00:00:00 2001 From: Anton Yarmolenko Date: Mon, 22 Jan 2024 10:33:42 +0100 Subject: [PATCH 04/10] chore: little refactor --- WhatsNew/WhatsNew/Presentation/WhatsNewViewModel.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/WhatsNew/WhatsNew/Presentation/WhatsNewViewModel.swift b/WhatsNew/WhatsNew/Presentation/WhatsNewViewModel.swift index f6097bfac..7ea8315a3 100644 --- a/WhatsNew/WhatsNew/Presentation/WhatsNewViewModel.swift +++ b/WhatsNew/WhatsNew/Presentation/WhatsNewViewModel.swift @@ -59,9 +59,8 @@ public class WhatsNewViewModel: ObservableObject { if let imageOrTitle = config.uiComponents.whatsNewImageOrTitlePageSkip, !imageOrTitle.isEmpty { return domain.filter { $0.image != imageOrTitle && $0.title != imageOrTitle } - } else { - return domain } + return domain } private func loadWhatsNewModel() -> WhatsNewModel? { From e47e4fa0f69efe0cbb67ca54d709e25370f41872 Mon Sep 17 00:00:00 2001 From: Anton Yarmolenko Date: Mon, 22 Jan 2024 10:37:26 +0100 Subject: [PATCH 05/10] chore: changed back gitignor --- .gitignore | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index a339ffb50..8a80e27f8 100644 --- a/.gitignore +++ b/.gitignore @@ -115,5 +115,4 @@ vendor/ venv/ Podfile.lock config_settings.yaml -default_config/ -default_config/config_settings.yaml +default_config/ \ No newline at end of file From 8e099406e160c0ce200fe37194987a58bbb33f0b Mon Sep 17 00:00:00 2001 From: Anton Yarmolenko Date: Mon, 22 Jan 2024 13:42:03 +0100 Subject: [PATCH 06/10] chore: little refactor --- Core/Core/Configuration/Config/UIComponentsConfig.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/Core/Configuration/Config/UIComponentsConfig.swift b/Core/Core/Configuration/Config/UIComponentsConfig.swift index 027f7d639..2adc807b9 100644 --- a/Core/Core/Configuration/Config/UIComponentsConfig.swift +++ b/Core/Core/Configuration/Config/UIComponentsConfig.swift @@ -21,9 +21,9 @@ public class UIComponentsConfig: NSObject { public let whatsNewImageOrTitlePageSkip: String? init(dictionary: [String: Any]) { - courseNestedListEnabled = dictionary[Keys.courseNestedListEnabled.rawValue] as? Bool ?? false - courseBannerEnabled = dictionary[Keys.courseBannerEnabled.rawValue] as? Bool ?? false - courseTopTabBarEnabled = dictionary[Keys.courseTopTabBarEnabled.rawValue] as? Bool ?? false + courseNestedListEnabled = dictionary[Keys.courseNestedListEnabled] as? Bool ?? false + courseBannerEnabled = dictionary[Keys.courseBannerEnabled] as? Bool ?? false + courseTopTabBarEnabled = dictionary[Keys.courseTopTabBarEnabled] as? Bool ?? false whatsNewImageOrTitlePageSkip = dictionary[Keys.whatsNewImageOrTitlePageSkip] as? String super.init() } From 46b82aa985dc482e98a9cd9ce93ff884a04bf245 Mon Sep 17 00:00:00 2001 From: Anton Yarmolenko Date: Tue, 23 Jan 2024 16:39:36 +0100 Subject: [PATCH 07/10] chore: deleted FF --- Core/Core/Configuration/Config/UIComponentsConfig.swift | 3 --- OpenEdX/RouteController.swift | 2 +- OpenEdX/Router.swift | 2 +- WhatsNew/WhatsNew/Presentation/WhatsNewView.swift | 2 +- WhatsNew/WhatsNew/Presentation/WhatsNewViewModel.swift | 8 +------- WhatsNew/WhatsNewTests/Presentation/WhatsNewTests.swift | 6 ++---- 6 files changed, 6 insertions(+), 17 deletions(-) diff --git a/Core/Core/Configuration/Config/UIComponentsConfig.swift b/Core/Core/Configuration/Config/UIComponentsConfig.swift index 2adc807b9..1a9e23a93 100644 --- a/Core/Core/Configuration/Config/UIComponentsConfig.swift +++ b/Core/Core/Configuration/Config/UIComponentsConfig.swift @@ -11,20 +11,17 @@ private enum Keys: String, RawStringExtractable { case courseNestedListEnabled = "COURSE_NESTED_LIST_ENABLED" case courseTopTabBarEnabled = "COURSE_TOP_TAB_BAR_ENABLED" case courseBannerEnabled = "COURSE_BANNER_ENABLED" - case whatsNewImageOrTitlePageSkip = "WHATS_NEW_IMAGE_OR_TITLE_TO_SKIP_PAGE" } public class UIComponentsConfig: NSObject { public var courseNestedListEnabled: Bool = false public var courseBannerEnabled: Bool public var courseTopTabBarEnabled: Bool - public let whatsNewImageOrTitlePageSkip: String? init(dictionary: [String: Any]) { courseNestedListEnabled = dictionary[Keys.courseNestedListEnabled] as? Bool ?? false courseBannerEnabled = dictionary[Keys.courseBannerEnabled] as? Bool ?? false courseTopTabBarEnabled = dictionary[Keys.courseTopTabBarEnabled] as? Bool ?? false - whatsNewImageOrTitlePageSkip = dictionary[Keys.whatsNewImageOrTitlePageSkip] as? String super.init() } } diff --git a/OpenEdX/RouteController.swift b/OpenEdX/RouteController.swift index 006c26262..70bae693c 100644 --- a/OpenEdX/RouteController.swift +++ b/OpenEdX/RouteController.swift @@ -65,7 +65,7 @@ class RouteController: UIViewController { var storage = Container.shared.resolve(WhatsNewStorage.self)! let config = Container.shared.resolve(ConfigProtocol.self)! - let viewModel = WhatsNewViewModel(storage: storage, config: config) + let viewModel = WhatsNewViewModel(storage: storage) let shouldShowWhatsNew = viewModel.shouldShowWhatsNew() if shouldShowWhatsNew && config.features.whatNewEnabled { diff --git a/OpenEdX/Router.swift b/OpenEdX/Router.swift index fc41ac63a..9819bf335 100644 --- a/OpenEdX/Router.swift +++ b/OpenEdX/Router.swift @@ -63,7 +63,7 @@ public class Router: AuthorizationRouter, var storage = Container.shared.resolve(WhatsNewStorage.self)! let config = Container.shared.resolve(ConfigProtocol.self)! - let viewModel = WhatsNewViewModel(storage: storage, sourceScreen: sourceScreen, config: config) + let viewModel = WhatsNewViewModel(storage: storage, sourceScreen: sourceScreen) let whatsNew = WhatsNewView(router: Container.shared.resolve(WhatsNewRouter.self)!, viewModel: viewModel) let shouldShowWhatsNew = viewModel.shouldShowWhatsNew() diff --git a/WhatsNew/WhatsNew/Presentation/WhatsNewView.swift b/WhatsNew/WhatsNew/Presentation/WhatsNewView.swift index 8b3798a7e..cbc1cb42f 100644 --- a/WhatsNew/WhatsNew/Presentation/WhatsNewView.swift +++ b/WhatsNew/WhatsNew/Presentation/WhatsNewView.swift @@ -153,7 +153,7 @@ struct WhatsNewView_Previews: PreviewProvider { static var previews: some View { WhatsNewView( router: WhatsNewRouterMock(), - viewModel: WhatsNewViewModel(storage: WhatsNewStorageMock(), config: ConfigMock()) + viewModel: WhatsNewViewModel(storage: WhatsNewStorageMock()) ) .loadFonts() } diff --git a/WhatsNew/WhatsNew/Presentation/WhatsNewViewModel.swift b/WhatsNew/WhatsNew/Presentation/WhatsNewViewModel.swift index 7ea8315a3..12eb34b78 100644 --- a/WhatsNew/WhatsNew/Presentation/WhatsNewViewModel.swift +++ b/WhatsNew/WhatsNew/Presentation/WhatsNewViewModel.swift @@ -14,12 +14,10 @@ public class WhatsNewViewModel: ObservableObject { @Published var newItems: [WhatsNewPage] = [] private let storage: WhatsNewStorage var sourceScreen: LogistrationSourceScreen - private let config: ConfigProtocol - public init(storage: WhatsNewStorage, sourceScreen: LogistrationSourceScreen = .default, config: ConfigProtocol) { + public init(storage: WhatsNewStorage, sourceScreen: LogistrationSourceScreen = .default) { self.storage = storage self.sourceScreen = sourceScreen - self.config = config newItems = loadWhatsNew() } @@ -56,10 +54,6 @@ public class WhatsNewViewModel: ObservableObject { func loadWhatsNew() -> [WhatsNewPage] { guard let domain = loadWhatsNewModel()?.domain else { return [] } - if let imageOrTitle = config.uiComponents.whatsNewImageOrTitlePageSkip, - !imageOrTitle.isEmpty { - return domain.filter { $0.image != imageOrTitle && $0.title != imageOrTitle } - } return domain } diff --git a/WhatsNew/WhatsNewTests/Presentation/WhatsNewTests.swift b/WhatsNew/WhatsNewTests/Presentation/WhatsNewTests.swift index dd4a83b21..7c6542b16 100644 --- a/WhatsNew/WhatsNewTests/Presentation/WhatsNewTests.swift +++ b/WhatsNew/WhatsNewTests/Presentation/WhatsNewTests.swift @@ -12,16 +12,14 @@ import Core final class WhatsNewTests: XCTestCase { func testGetVersion() throws { - let config = ConfigMock() - let viewModel = WhatsNewViewModel(storage: WhatsNewStorageMock(), config: config) + let viewModel = WhatsNewViewModel(storage: WhatsNewStorageMock()) let version = viewModel.getVersion() XCTAssertNotNil(version) XCTAssertTrue(version == "1.0") } func testshouldShowWhatsNew() throws { - let config = ConfigMock() - let viewModel = WhatsNewViewModel(storage: WhatsNewStorageMock(), config: config) + let viewModel = WhatsNewViewModel(storage: WhatsNewStorageMock()) let version = viewModel.getVersion() XCTAssertNotNil(version) XCTAssertTrue(viewModel.shouldShowWhatsNew()) From 8baff13260af5d38fa9cedc9a9af3b432ea467be Mon Sep 17 00:00:00 2001 From: Anton Yarmolenko Date: Tue, 23 Jan 2024 18:32:05 +0100 Subject: [PATCH 08/10] chore: added copying of whatsnew json file --- Documentation/Theming_implementation.md | 11 ++++++++++ config_script/whitelabel.py | 29 +++++++++++++++++++++---- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/Documentation/Theming_implementation.md b/Documentation/Theming_implementation.md index 31980d517..050f38afa 100644 --- a/Documentation/Theming_implementation.md +++ b/Documentation/Theming_implementation.md @@ -97,6 +97,17 @@ font: bold: 'FontName-Bold' ``` +### What's New +The `whitelabel.yaml` configuration may contain the path to a What's New json file, and an existing json file in the project will be replaced with this json file. + +For this function, the configuration must contain the following parameters: +```yaml +whatsnew: + whatsnew_import_file_path: 'path/to/importing/whats_new.json' # path to what's new json file what should be imported to project + project_whatsnew_file_path: 'path/to/json/file/in/project/WhatsNew.json' # path to existing json-file in project +``` + + ### Log level You can set the log level to 'DEBUG' by adding the `-v` parameter to the script running. The default log level is 'WARN' diff --git a/config_script/whitelabel.py b/config_script/whitelabel.py index fec095f62..45d6b5085 100644 --- a/config_script/whitelabel.py +++ b/config_script/whitelabel.py @@ -58,6 +58,9 @@ class WhitelabelApp: medium: 'FontName-Medium' semiBold: 'FontName-Semibold' bold: 'FontName-Bold' + whatsnew: + whatsnew_import_file_path: 'path/to/importing/whats_new.json' + project_whatsnew_file_path: 'path/to/json/file/in/project/WhatsNew.json' """) def __init__(self, **kwargs): @@ -68,6 +71,7 @@ def __init__(self, **kwargs): self.assets = kwargs.get('assets', {}) self.project_config = kwargs.get('project_config', {}) self.font = kwargs.get('font', {}) + self.whatsnew = kwargs.get('whatsnew', {}) if "project_path" in self.project_config: self.config_project_path = self.project_config["project_path"] @@ -78,6 +82,7 @@ def whitelabel(self): # Update the properties, resources, and configuration of the current app. self.copy_assets() self.copy_font() + self.copy_whatsnew() self.set_app_project_config() def copy_assets(self): @@ -425,7 +430,7 @@ def copy_font(self): if "project_font_file_path" in self.font: project_font_file_path = self.font["project_font_file_path"] # if source and destination file exist - self.copy_font_file(font_import_file_path, project_font_file_path) + self.copy_file(font_import_file_path, project_font_file_path, "Font") else: logging.error("'project_font_file_path' not found in config") else: @@ -440,14 +445,14 @@ def copy_font(self): else: logging.debug("Font not found in config") - def copy_font_file(self, file_src, file_dest): - # try to copy font file and show success/error message + def copy_file(self, file_src, file_dest, title): + # try to copy file and show success/error message try: shutil.copy(file_src, file_dest) except IOError as e: logging.error("Unable to copy file. "+e) else: - logging.debug("Font was copied to project") + logging.debug(title+" file was copied to project") def set_font_names(self, font_names): if "project_font_names_json_path" in self.font: @@ -469,6 +474,22 @@ def set_font_names(self, font_names): else: logging.error("'project_font_names_json_path' not found in config") + def copy_whatsnew(self): + # check if whatsnew config exists + if self.whatsnew: + if "whatsnew_import_file_path" in self.whatsnew: + whatsnew_import_file_path = self.whatsnew["whatsnew_import_file_path"] + if "project_whatsnew_file_path" in self.whatsnew: + project_whatsnew_file_path = self.whatsnew["project_whatsnew_file_path"] + # if source and destination file exist + self.copy_file(whatsnew_import_file_path, project_whatsnew_file_path, "What's new") + else: + logging.error("'project_whatsnew_file_path' not found in config") + else: + logging.error("'whatsnew_import_file_path' not found in config") + else: + logging.debug("What's New not found in config") + def main(): """ Parse the command line arguments, and pass them to WhitelabelApp. From c81cc94c16680c04f5e85bf84abc9b5f9b482151 Mon Sep 17 00:00:00 2001 From: Anton Yarmolenko Date: Tue, 23 Jan 2024 18:37:33 +0100 Subject: [PATCH 09/10] chore: returned back changes --- Core/Core/Configuration/Config/UIComponentsConfig.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Core/Core/Configuration/Config/UIComponentsConfig.swift b/Core/Core/Configuration/Config/UIComponentsConfig.swift index 1a9e23a93..4dd4f8be6 100644 --- a/Core/Core/Configuration/Config/UIComponentsConfig.swift +++ b/Core/Core/Configuration/Config/UIComponentsConfig.swift @@ -7,7 +7,7 @@ import Foundation -private enum Keys: String, RawStringExtractable { +private enum Keys: String { case courseNestedListEnabled = "COURSE_NESTED_LIST_ENABLED" case courseTopTabBarEnabled = "COURSE_TOP_TAB_BAR_ENABLED" case courseBannerEnabled = "COURSE_BANNER_ENABLED" @@ -19,9 +19,9 @@ public class UIComponentsConfig: NSObject { public var courseTopTabBarEnabled: Bool init(dictionary: [String: Any]) { - courseNestedListEnabled = dictionary[Keys.courseNestedListEnabled] as? Bool ?? false - courseBannerEnabled = dictionary[Keys.courseBannerEnabled] as? Bool ?? false - courseTopTabBarEnabled = dictionary[Keys.courseTopTabBarEnabled] as? Bool ?? false + courseNestedListEnabled = dictionary[Keys.courseNestedListEnabled.rawValue] as? Bool ?? false + courseBannerEnabled = dictionary[Keys.courseBannerEnabled.rawValue] as? Bool ?? false + courseTopTabBarEnabled = dictionary[Keys.courseTopTabBarEnabled.rawValue] as? Bool ?? false super.init() } } From 42dd169f7425337b795a0d3cce94f6ba1b1e9a88 Mon Sep 17 00:00:00 2001 From: Anton Yarmolenko Date: Fri, 26 Jan 2024 13:42:42 +0100 Subject: [PATCH 10/10] chore: address review feedback --- Documentation/Theming_implementation.md | 2 +- config_script/whitelabel.py | 24 +++++++++++++++++------- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/Documentation/Theming_implementation.md b/Documentation/Theming_implementation.md index 050f38afa..c92f32be0 100644 --- a/Documentation/Theming_implementation.md +++ b/Documentation/Theming_implementation.md @@ -104,7 +104,7 @@ For this function, the configuration must contain the following parameters: ```yaml whatsnew: whatsnew_import_file_path: 'path/to/importing/whats_new.json' # path to what's new json file what should be imported to project - project_whatsnew_file_path: 'path/to/json/file/in/project/WhatsNew.json' # path to existing json-file in project + project_whatsnew_file_path: 'path/to/json/file/in/project/whats_new.json' # path to existing json-file in project ``` diff --git a/config_script/whitelabel.py b/config_script/whitelabel.py index 45d6b5085..d7295d4d9 100644 --- a/config_script/whitelabel.py +++ b/config_script/whitelabel.py @@ -60,7 +60,7 @@ class WhitelabelApp: bold: 'FontName-Bold' whatsnew: whatsnew_import_file_path: 'path/to/importing/whats_new.json' - project_whatsnew_file_path: 'path/to/json/file/in/project/WhatsNew.json' + project_whatsnew_file_path: 'path/to/json/file/in/project/whats_new.json' """) def __init__(self, **kwargs): @@ -73,17 +73,21 @@ def __init__(self, **kwargs): self.font = kwargs.get('font', {}) self.whatsnew = kwargs.get('whatsnew', {}) - if "project_path" in self.project_config: - self.config_project_path = self.project_config["project_path"] + if self.project_config: + if "project_path" in self.project_config: + self.config_project_path = self.project_config["project_path"] + else: + logging.error("Path to project file is not defined") else: - logging.error("Path to project file is not defined") + logging.debug("Project settings config not found") def whitelabel(self): # Update the properties, resources, and configuration of the current app. self.copy_assets() self.copy_font() self.copy_whatsnew() - self.set_app_project_config() + if self.project_config: + self.set_app_project_config() def copy_assets(self): if self.assets: @@ -92,7 +96,7 @@ def copy_assets(self): self.replace_colors(asset) self.replace_app_icon(asset) else: - logging.debug("Assets not found") + logging.debug("Assets config not found") def replace_images(self, asset_data): asset = asset_data[1] @@ -482,7 +486,13 @@ def copy_whatsnew(self): if "project_whatsnew_file_path" in self.whatsnew: project_whatsnew_file_path = self.whatsnew["project_whatsnew_file_path"] # if source and destination file exist - self.copy_file(whatsnew_import_file_path, project_whatsnew_file_path, "What's new") + if os.path.exists(whatsnew_import_file_path): + if os.path.exists(project_whatsnew_file_path): + self.copy_file(whatsnew_import_file_path, project_whatsnew_file_path, "What's new") + else: + logging.error(project_whatsnew_file_path+" file doesn't exist") + else: + logging.error(whatsnew_import_file_path+" file doesn't exist") else: logging.error("'project_whatsnew_file_path' not found in config") else: