Implement theme-cmd 67/310967/5
authorSangyoon Jang <jeremy.jang@samsung.com>
Fri, 10 May 2024 08:54:25 +0000 (17:54 +0900)
committerSangyoon Jang <jeremy.jang@samsung.com>
Tue, 21 May 2024 06:36:13 +0000 (15:36 +0900)
theme-cmd is a command-line tool for tizen-theme-manager,
for setting default theme or getting installed theme info.

$ theme-cmd -h
Allowed options:
  -h, --help             display this help message
  -s, --set-default      set default theme
  -g, --get              get specific theme info
  -c, --get-current      get current theme info
  -l, --list             print list of installed themes

Change-Id: I6001685cc053d10845347a110472539da33a536e
Signed-off-by: Sangyoon Jang <jeremy.jang@samsung.com>
CMakeLists.txt
src/CMakeLists.txt
src/theme_cmd/CMakeLists.txt [new file with mode: 0644]
src/theme_cmd/main.cc [new file with mode: 0644]
src/theme_cmd/parser.cc [new file with mode: 0644]
src/theme_cmd/parser.h [new file with mode: 0644]
src/theme_cmd/theme_cmd.cc [new file with mode: 0644]
src/theme_cmd/theme_cmd.h [new file with mode: 0644]

index 24cb26b70fb73a292e3c295601b693012b0e3571..80c94f1c7e3be893d7fa239a3b30d427ef06e135 100644 (file)
@@ -16,6 +16,7 @@ SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed,--gc-sections -pie")
 SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules/")
 
 ## Targets
+SET(TARGET_THEME_CMD "theme-cmd")
 SET(TARGET_THEME_PROVIDER "theme-provider")
 SET(TARGET_TIZEN_THEME "tizen-theme")
 SET(TARGET_TIZEN_THEME_API "capi-appfw-tizen-theme")
index 6d12f77dc57d6acfefd074a98bba869a00a7ffb8..077de1e94e7c0086456cae97fdab0f4129850920 100644 (file)
@@ -1,5 +1,6 @@
 ADD_SUBDIRECTORY(api)
 ADD_SUBDIRECTORY(main)
 ADD_SUBDIRECTORY(theme)
+ADD_SUBDIRECTORY(theme_cmd)
 ADD_SUBDIRECTORY(theme_plugin)
 ADD_SUBDIRECTORY(theme_provider)
diff --git a/src/theme_cmd/CMakeLists.txt b/src/theme_cmd/CMakeLists.txt
new file mode 100644 (file)
index 0000000..9e475d0
--- /dev/null
@@ -0,0 +1,14 @@
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} CMD_SRCS)
+ADD_EXECUTABLE(${TARGET_THEME_CMD} ${CMD_SRCS})
+TARGET_INCLUDE_DIRECTORIES(${TARGET_THEME_CMD} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../")
+
+APPLY_PKG_CONFIG(${TARGET_THEME_CMD} PUBLIC
+  DATABASE_DEPS
+  GLIB_DEPS
+)
+
+TARGET_LINK_LIBRARIES(${TARGET_THEME_CMD} PRIVATE ${TARGET_TIZEN_THEME} ${TARGET_TIZEN_THEME_PROVIDER})
+SET_TARGET_PROPERTIES(${TARGET_THEME_CMD} PROPERTIES COMPILE_FLAGS "-fPIE")
+SET_TARGET_PROPERTIES(${TARGET_THEME_CMD} PROPERTIES LINK_FLAGS "-pie")
+
+INSTALL(TARGETS ${TARGET_THEME_CMD} DESTINATION ${BINDIR})
\ No newline at end of file
diff --git a/src/theme_cmd/main.cc b/src/theme_cmd/main.cc
new file mode 100644 (file)
index 0000000..418d5b2
--- /dev/null
@@ -0,0 +1,38 @@
+// Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a apache 2.0 license that can be
+// found in the LICENSE file.
+
+#include <any>
+#include <exception>
+#include <iostream>
+#include <map>
+#include <string>
+
+#include "theme_cmd/parser.h"
+#include "theme_cmd/theme_cmd.h"
+
+int main(int argc, char* argv[]) {
+  ttm::cmd::Parser parser;
+  auto args = parser.Parse(argc, argv);
+  if (args.empty())
+    return 1;
+
+  try {
+    ttm::cmd::Cmd cmd;
+    if (args.find("set-default") != args.end()) {
+      std::string id = std::any_cast<std::string>(args["set-default"]);
+      cmd.SetDefaultTheme(id);
+    } else if (args.find("get") != args.end()) {
+      std::string id = std::any_cast<std::string>(args["get"]);
+      cmd.PrintThemeInfo(id);
+    } else if (args.find("get-current") != args.end()) {
+      cmd.PrintCurrentTheme();
+    } else if (args.find("list") != args.end()) {
+      cmd.PrintThemeList();
+    }
+  } catch (const std::exception& e) {
+    std::cerr << "exception caught: " << e.what() << std::endl;
+  }
+
+  return 0;
+}
diff --git a/src/theme_cmd/parser.cc b/src/theme_cmd/parser.cc
new file mode 100644 (file)
index 0000000..dc6744f
--- /dev/null
@@ -0,0 +1,82 @@
+// Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a apache 2.0 license that can be
+// found in the LICENSE file.
+
+#include "theme_cmd/parser.h"
+
+#include <getopt.h>
+
+#include <any>
+#include <iostream>
+#include <map>
+#include <string>
+
+namespace {
+
+constexpr char short_opts[] = "hs:g:cl";
+const struct option long_opts[] = {
+  { "help", no_argument, nullptr, 'h' },
+  { "set-default", required_argument, nullptr, 's' },
+  { "get", required_argument, nullptr, 'g' },
+  { "get-current", no_argument, nullptr, 'c' },
+  { "list", no_argument, nullptr, 'l' },
+  { 0, 0, 0, 0 },
+};
+
+const char kHelpMessage[] = R"(Allowed options:
+  -h, --help             display this help message
+  -s, --set-default      set default theme
+  -g, --get              get specific theme info
+  -c, --get-current      get current theme info
+  -l, --list             print list of installed themes
+)";
+
+}  // namespace
+
+namespace ttm {
+namespace cmd {
+
+std::map<std::string, std::any> Parser::Parse(int argc, char* argv[]) {
+  std::map<std::string, std::any> args;
+  while (true) {
+    int opt = getopt_long(argc, argv, short_opts, long_opts, nullptr);
+    if (opt == -1)
+      break;
+
+    switch (opt) {
+      case 'h':
+        PrintHelp();
+        return {};
+      case 's':
+        if (!optarg) {
+          std::cerr << "missing argument for \"set-default\"" << std::endl;
+          return {};
+        }
+        args["set-default"] = std::string(optarg);
+        break;
+      case 'g':
+        if (!optarg) {
+          std::cerr << "missing argument for \"get\"" << std::endl;
+          return {};
+        }
+        args["get"] = std::string(optarg);
+        break;
+      case 'c':
+        args["get-current"] = true;
+        break;
+      case 'l':
+        args["list"] = true;
+        break;
+      default:
+        break;
+    }
+  }
+  return args;
+}
+
+void Parser::PrintHelp() {
+  std::cerr << kHelpMessage;
+}
+
+}  // namespace cmd
+}  // namespace ttm
diff --git a/src/theme_cmd/parser.h b/src/theme_cmd/parser.h
new file mode 100644 (file)
index 0000000..7dc5e60
--- /dev/null
@@ -0,0 +1,28 @@
+// Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a apache 2.0 license that can be
+// found in the LICENSE file.
+
+#ifndef THEME_CMD_PARSER_H_
+#define THEME_CMD_PARSER_H_
+
+#include <any>
+#include <map>
+#include <string>
+
+namespace ttm {
+namespace cmd {
+
+class Parser {
+ public:
+  Parser() {}
+  ~Parser() {}
+  std::map<std::string, std::any> Parse(int argc, char* argv[]);
+
+ private:
+  void PrintHelp();
+};
+
+}  // cmd
+}  // ttm
+
+#endif  // THEME_CMD_PARSER_H_
diff --git a/src/theme_cmd/theme_cmd.cc b/src/theme_cmd/theme_cmd.cc
new file mode 100644 (file)
index 0000000..734057f
--- /dev/null
@@ -0,0 +1,91 @@
+// Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a apache 2.0 license that can be
+// found in the LICENSE file.
+
+#include "theme_cmd/theme_cmd.h"
+
+#include <iostream>
+#include <memory>
+#include <string>
+
+#include "theme/dbus/request_broker.h"
+#include "theme/loader/theme_info_loader.h"
+#include "theme_provider/theme_info_proxy.h"
+
+namespace {
+
+constexpr char kThemeDbPath[] = "/opt/dbspace/.tizen_theme.db";
+
+}  // namespace
+
+namespace ttm {
+namespace cmd {
+
+Cmd::Cmd() {
+  if (ttm::dbus::RequestBroker::GetInst().GetConnection() == nullptr) {
+    std::cout << "Running in offline mode" << std::endl;
+    loader_ = nullptr;
+    offline_mode_ = true;
+  } else {
+    loader_ = std::make_shared<ttm::loader::ThemeInfoLoader>();
+    offline_mode_ = false;
+  }
+}
+
+Cmd::~Cmd() {
+}
+
+void Cmd::SetDefaultTheme(const std::string& id) {
+  if (offline_mode_) {
+    ttm::provider::ThemeInfoProxy proxy(kThemeDbPath);
+    proxy.SetCurrentTheme(id);
+  } else {
+    loader_->SetCurrent(id);
+  }
+}
+
+void Cmd::PrintCurrentTheme() {
+  std::shared_ptr<ttm::loader::ThemeInfo> theme;
+  if (offline_mode_) {
+    ttm::provider::ThemeInfoProxy proxy(kThemeDbPath);
+    theme = proxy.GetLoadedTheme();
+  } else {
+    theme = loader_->LoadCurrent();
+  }
+  if (!theme) {
+    std::cerr << "Failed to load current theme" << std::endl;
+    return;
+  }
+  std::cout << theme->GetId() << std::endl;
+}
+
+void Cmd::PrintThemeInfo(const std::string& id) {
+  std::shared_ptr<ttm::loader::ThemeInfo> theme;
+  if (offline_mode_) {
+    ttm::provider::ThemeInfoProxy proxy(kThemeDbPath);
+    theme = proxy.LoadTheme(id);
+  } else {
+    theme = loader_->Load(id);
+  }
+  if (!theme) {
+    std::cerr << "Failed to load theme info" << std::endl;
+    return;
+  }
+  std::cout << theme->GetId() << " " << theme->GetVersion() << std::endl;
+}
+
+void Cmd::PrintThemeList() {
+  std::vector<std::string> list;
+  if (offline_mode_) {
+    ttm::provider::ThemeInfoProxy proxy(kThemeDbPath);
+    list = proxy.GetThemeIds();
+  } else {
+    list = loader_->QueryThemeId();
+  }
+  for (const auto& id : list) {
+    std::cout << id << std::endl;
+  }
+}
+
+}  // namespace cmd
+}  // namespace ttm
diff --git a/src/theme_cmd/theme_cmd.h b/src/theme_cmd/theme_cmd.h
new file mode 100644 (file)
index 0000000..4fea2b8
--- /dev/null
@@ -0,0 +1,36 @@
+// Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a apache 2.0 license that can be
+// found in the LICENSE file.
+
+#ifndef THEME_CMD_THEME_CMD_H_
+#define THEME_CMD_THEME_CMD_H_
+
+
+#include <memory>
+
+#include "theme/loader/theme_info.h"
+#include "theme/loader/theme_info_loader.h"
+
+namespace ttm {
+namespace cmd {
+
+class Cmd {
+ public:
+  Cmd();
+  ~Cmd();
+
+  void SetDefaultTheme(const std::string& id);
+  void PrintCurrentTheme();
+  void PrintThemeInfo(const std::string& id);
+  void PrintThemeList();
+
+ private:
+  // NOTE: current ThemeInfoLoader class cannot be used with unique_ptr
+  std::shared_ptr<ttm::loader::ThemeInfoLoader> loader_;
+  bool offline_mode_;
+};
+
+}  // namespace cmd
+}  // namespace ttm
+
+#endif  // THEME_CMD_THEME_CMD_H_