summaryrefslogtreecommitdiffstats
path: root/src/rttt/config.hpp
blob: ed8ef3525c780221cc48a63a06b4ce89a63188d3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#pragma once

#include <filesystem>
#include <fstream>
#include <iostream>
#include <random>

#include "nlohmann/json.hpp"

#include "functional.hpp"
#include "rttt/prompt.hpp"

namespace rttt {

namespace config {

inline std::string random_string(size_t size) {
  const std::string characters =
      "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

  std::default_random_engine generator(time(0));
  std::uniform_int_distribution<> distribution(0, characters.size() - 1);

  std::string random_string;
  random_string.resize(size);

  for (std::size_t i = 0; i < size; ++i) {
    random_string[i] = characters[distribution(generator)];
  }

  return random_string;
}

inline std::filesystem::path getPath() {
  auto path_char = std::getenv("XDG_CONFIG_HOME");
  if (path_char != NULL)
    return std::filesystem::path(std::filesystem::path(path_char) / "rttt");
  std::filesystem::path path =
      std::filesystem::path(std::getenv("HOME")) / ".config/rttt";
  return std::filesystem::absolute(path);
}

inline std::filesystem::path getFilePath() { return getPath() / "config.json"; }

// TODO: Move to thing.hpp (and source specific configuration to their files)
nlohmann::json defaultConfig() {
  nlohmann::json config;
  config["reddit"]["client_id"] = "8yDBiibHONI95SeMWLZspg";
  config["reddit"]["device_id"] = rttt::config::random_string(25);
  config["reddit"]["refresh_token"] = "";
  config["twitter"]["api_key"] = "FEZfkDOci69v51iVgkUsfYZuK";
  config["twitter"]["api_secret_key"] =
      "gJmmYEh4SWRvg2V4kRWbMtgbXDrpgKYV2EIFFtWJkC5pDuH0ra";
  config["rss"]["opml_file"] = rttt::config::getPath() / "subscriptions.opml";
  config["open_command"] = "xdg-open";
  config["start_path"] = "/hn/top";
  return config;
}

inline bool save(const nlohmann::json &json) {
  std::ofstream file;
  file.open(getFilePath().c_str());
  file << json.dump(2) << std::endl;
  file.close();
  return true;
}

inline nlohmann::json load() {
  std::filesystem::path fn = "config.json";
  auto path = getPath();
  nlohmann::json config;
  if (!std::filesystem::exists(path)) {
    std::filesystem::create_directory(path);
  }
  auto fpath = getFilePath();
  if (!std::filesystem::exists(fpath)) {
    config = defaultConfig();
    save(config);
  } else {
    FILE *pFile;
    pFile = fopen(fpath.c_str(), "r");
    auto saved_config = nlohmann::json::parse(pFile);

    // Make sure config contains all expected values
    config = defaultConfig();
    // Overwrite with saved values
    config.update(saved_config);
  }
  return config;
}

inline std::filesystem::path get_data_path() {
  auto path_char = std::getenv("XDG_DATA_HOME");
  if (path_char != NULL)
    return std::filesystem::path(std::filesystem::path(path_char) / "rttt");
  std::filesystem::path path =
      std::filesystem::path(std::getenv("HOME")) / ".local/share/rttt";
  return std::filesystem::absolute(path);
}

template <typename T>
nlohmann::json load_data_from_file_or(const T &default_states,
                                      const std::filesystem::path &fn) {
  auto path = get_data_path();
  if (!std::filesystem::exists(path)) {
    std::filesystem::create_directory(path);
  }
  auto fpath = path / fn;

  nlohmann::json data;

  if (!std::filesystem::exists(fpath)) {
    nlohmann::json j = default_states;
    return j;
  }

  FILE *p_file;
  p_file = fopen(fpath.c_str(), "r");
  return nlohmann::json::parse(p_file);
}

bool save_to_data_path(const nlohmann::json &json,
                       const std::filesystem::path &fn) {
  auto path = get_data_path() / fn;
  std::ofstream file;
  file.open(path);
  file << json.dump() << std::endl;
  file.close();
  return true;
}

template <typename T>
nlohmann::json load_item_view_states_or(const T &default_states) {
  return load_data_from_file_or(default_states, "item_view_state.json");
}

bool save_item_view_states(const nlohmann::json &json) {
  return save_to_data_path(json, "item_view_state.json");
}

auto load_prompt_state_or(rttt::prompt::state &default_state) {
  return with([&default_state](rttt::prompt::state &state) -> rttt::prompt::state & {
    state = load_data_from_file_or(default_state, "prompt_state.json");
    return state;
  });
}

bool save_prompt_state(const nlohmann::json &json) {
  return save_to_data_path(json, "prompt_state.json");
}

} // namespace config
} // namespace rttt