ndm  0.2.8
Utils.hh
1 #pragma once
2 #include <sys/stat.h>
3 #include <libgen.h>
4 #include <cmath>
5 #include <limits>
6 #include <fstream>
7 #include <string>
8 #include <sstream>
9 #include <bitset>
10 #include <google/protobuf/util/json_util.h>
11 #include "Point.pb.h"
12 #include "ndm.hh"
13 
14 namespace NDM {
15 namespace Utils {
16 
17 inline bool is_equal(double a, double b, double error_factor = 1.0)
18 {
19  return a == b ||
20  std::abs(a - b) < std::abs(std::fmin(a, b)) * std::numeric_limits<double>::epsilon() * error_factor;
21 }
22 
23 inline void asci_to_protobuf(std::string a, std::string & p)
24 {
25  std::stringstream sstream(a);
26  p.clear();
27  while (sstream.good()) {
28  std::bitset<8> bits;
29  sstream >> bits;
30  char c = char(bits.to_ulong());
31  p += c;
32  }
33 }
34 
35 inline void protobuf_to_asci(std::string p, std::string & a)
36 {
37  for (std::size_t i = 0; i < p.size(); ++i) {
38  std::bitset<8> xx = std::bitset<8>(p[i]);
39  a += xx.to_string();
40  }
41 }
42 inline int mkpath(const char * dir, mode_t mode)
43 {
44  struct stat st;
45  if (!dir) {
46  errno = EINVAL;
47  return 1;
48  }
49  if (!stat(dir, &st)) return 0;
50  mkpath(dirname(strdupa(dir)), mode);
51  return mkdir(dir, mode);
52 }
53 
54 inline std::string get_working_path()
55 {
56  char temp[128];
57  return (getcwd(temp, sizeof(temp)) ? std::string(temp) : std::string(""));
58 }
59 
60 inline bool ndm_init(std::string dir = "/tmp/")
61 {
62  std::string ndm_yaml;
63  ndm_yaml.append("base: \"" + dir + "/content\"\n");
64  ndm_yaml.append("cmd: \"" + dir + "/ndm.sh\"\n");
65  ndm_yaml.append("space:\n");
66  ndm_yaml.append(" axes:\n");
67  ndm_yaml.append(" - name: \"axis1\"\n");
68  ndm_yaml.append(" min: 0\n");
69  ndm_yaml.append(" max: 1\n");
70  ndm_yaml.append(" level: 0\n");
71  std::ofstream ndm_yaml_out("ndm.yaml");
72  ndm_yaml_out << ndm_yaml;
73  ndm_yaml_out.close();
74 
75  std::string ndm_script;
76  ndm_script.append("#!/bin/bash\n");
77  ndm_script.append("export WKDIR=\"$NDMBASE/$NDMPATH\"\n");
78  ndm_script.append("mkdir -p $WKDIR && cd $WKDIR || exit 1\n");
79  ndm_script.append("(\n");
80  ndm_script.append("export\n");
81  ndm_script.append("ndm info\n");
82  ndm_script.append("# my job\n");
83  ndm_script.append("sleep 1\n");
84  ndm_script.append(") |& tee $WKDIR/ndm.log\n");
85  std::ofstream ndm_script_out("ndm.sh");
86  ndm_script_out << ndm_script;
87  chmod("ndm.sh", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
88  ndm_script_out.close();
89 
90  std::string ndm_runscript;
91  ndm_runscript.append("#!/bin/bash\n");
92  ndm_runscript.append("SLS_URL=${1-\"tcp://toolbox.localhost:41000\"}\n\n");
93  ndm_runscript.append("salsa-ndm -s $SLS_URL -c ndm.yaml\n");
94  std::ofstream ndm_runscript_out("run.sh");
95  ndm_runscript_out << ndm_runscript;
96  chmod("run.sh", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
97  ndm_runscript_out.close();
98 
99  spdlog::info("Files 'ndm.yaml', 'ndm.sh' and 'run.sh' generated");
100 
101  return true;
102 }
103 
104 inline bool ndm_info(std::string out = "")
105 {
106  const char* e = getenv("NDMPOINT");
107  std::string ndmpoint;
108  if (e) ndmpoint = e;
109 
110  if (ndmpoint.empty()) {
111  spdlog::error("Missing env variable '$NDMPOINT' !!!");
112  return false;
113  }
114  std::string ndmpoint_out;
115  NDM::Utils::asci_to_protobuf(ndmpoint, ndmpoint_out);
116  NDM::Point p;
117  bool b = p.ParseFromString(ndmpoint_out);
118 
119  google::protobuf::util::JsonPrintOptions options;
120  options.add_whitespace = true;
121  options.always_print_primitive_fields = true;
122  std::string result;
123  MessageToJsonString(p, &result, options);
124  spdlog::info("{}", result);
125  result = "";
126 
127  if (!out.empty()) {
128  std::ofstream outputfile(out);
129  options.add_whitespace = false;
130  MessageToJsonString(p, &result, options);
131  outputfile << result << std::endl;
132  outputfile.close();
133  spdlog::info("File '{}' was created.", out);
134  }
135 
136  return true;
137 }
138 
139 } // namespace Utils
140 } // namespace NDM