]> git.stg.codes - stg.git/blob - projects/sgconf/tariffs.cpp
4d4feb9a9aaeab66152d741cca9b47879d60bffa
[stg.git] / projects / sgconf / tariffs.cpp
1 #include "tariffs.h"
2
3 #include "api_action.h"
4 #include "options.h"
5 #include "config.h"
6
7 #include "stg/servconf.h"
8 #include "stg/servconf_types.h"
9 #include "stg/tariff_conf.h"
10 #include "stg/os_int.h"
11
12 #include <iostream>
13 #include <sstream>
14 #include <string>
15 #include <map>
16 #include <cassert>
17
18 namespace
19 {
20
21 std::string Indent(size_t level, bool dash = false)
22 {
23 if (level == 0)
24     return "";
25 return dash ? std::string(level * 4 - 2, ' ') + "- " : std::string(level * 4, ' ');
26 }
27
28 std::string PeriodToString(TARIFF::PERIOD period)
29 {
30 switch (period)
31     {
32     case TARIFF::DAY:
33         return "daily";
34     case TARIFF::MONTH:
35         return "monthly";
36     }
37 return "unknown";
38 }
39
40 std::string TraffTypeToString(int traffType)
41 {
42 switch (traffType)
43     {
44     case TRAFF_UP:
45         return "upload";
46     case TRAFF_DOWN:
47         return "download";
48     case TRAFF_UP_DOWN:
49         return "upload + download";
50     case TRAFF_MAX:
51         return "max(upload, download)";
52     }
53 return "unknown";
54 }
55
56 std::string TimeToString(int h, int m)
57 {
58 std::ostringstream stream;
59 stream << (h < 10 ? "0" : "") << h << ":"
60        << (m < 10 ? "0" : "") << m;
61 return stream.str();
62 }
63
64 void PrintDirPriceData(size_t dir, const DIRPRICE_DATA & data, size_t level)
65 {
66 std::string night = TimeToString(data.hNight, data.mNight);
67 std::string day = TimeToString(data.hDay, data.mDay);
68 std::cout << Indent(level, true) << "dir: " << dir << "\n"
69           << Indent(level)       << "'" << night << "' - '" << day << "': " << data.priceDayA << "/" << data.priceDayB << "\n"
70           << Indent(level)       << "'" << day << "' - '" << night << "': " << data.priceNightA << "/" << data.priceNightB << "\n"
71           << Indent(level)       << "threshold: " << data.threshold << "\n"
72           << Indent(level)       << "single price: " << (data.singlePrice ? "yes" : "no") << "\n"
73           << Indent(level)       << "discount: " << (data.noDiscount ? "no" : "yes") << "\n"; // Attention!
74 }
75
76 void PrintTariffConf(const TARIFF_CONF & conf, size_t level)
77 {
78 std::cout << Indent(level, true) << "name: " << conf.name << "\n"
79           << Indent(level)       << "fee: " << conf.fee << "\n"
80           << Indent(level)       << "free mb: " << conf.free << "\n"
81           << Indent(level)       << "passive cost: " << conf.passiveCost << "\n"
82           << Indent(level)       << "traff type: " << TraffTypeToString(conf.traffType) << "\n"
83           << Indent(level)       << "period: " << PeriodToString(conf.period) << "\n";
84 }
85
86 void PrintTariff(const STG::GET_TARIFF::INFO & info, size_t level = 0)
87 {
88 PrintTariffConf(info.tariffConf, level);
89 std::cout << Indent(level) << "dir prices:\n";
90 for (size_t i = 0; i < info.dirPrice.size(); ++i)
91     PrintDirPriceData(i, info.dirPrice[i], level + 1);
92 }
93
94 void SimpleCallback(bool result,
95                     const std::string & reason,
96                     void * /*data*/)
97 {
98 if (!result)
99     {
100     std::cerr << "Operation failed. Reason: '" << reason << "'." << std::endl;
101     return;
102     }
103 std::cout << "Success.\n";
104 }
105
106 void GetTariffsCallback(bool result,
107                         const std::string & reason,
108                         const std::vector<STG::GET_TARIFF::INFO> & info,
109                         void * /*data*/)
110 {
111 if (!result)
112     {
113     std::cerr << "Failed to get tariff list. Reason: '" << reason << "'." << std::endl;
114     return;
115     }
116 std::cout << "Tariffs:\n";
117 for (size_t i = 0; i < info.size(); ++i)
118     PrintTariff(info[i], 1);
119 }
120
121 void GetTariffCallback(bool result,
122                        const std::string & reason,
123                        const std::vector<STG::GET_TARIFF::INFO> & info,
124                        void * data)
125 {
126 assert(data != NULL && "Expecting pointer to std::string with the tariff's name.");
127 const std::string & name = *static_cast<const std::string *>(data);
128 if (!result)
129     {
130     std::cerr << "Failed to get tariff. Reason: '" << reason << "'." << std::endl;
131     return;
132     }
133 for (size_t i = 0; i < info.size(); ++i)
134     if (info[i].tariffConf.name == name)
135         PrintTariff(info[i]);
136 }
137
138 bool GetTariffsFunction(const SGCONF::CONFIG & config,
139                         const std::string & /*arg*/,
140                         const std::map<std::string, std::string> & /*options*/)
141 {
142 STG::SERVCONF proto(config.server.data(),
143                     config.port.data(),
144                     config.userName.data(),
145                     config.userPass.data());
146 return proto.GetTariffs(GetTariffsCallback, NULL) == STG::st_ok;
147 }
148
149 bool GetTariffFunction(const SGCONF::CONFIG & config,
150                        const std::string & arg,
151                        const std::map<std::string, std::string> & /*options*/)
152 {
153 STG::SERVCONF proto(config.server.data(),
154                     config.port.data(),
155                     config.userName.data(),
156                     config.userPass.data());
157 // STG currently doesn't support <GetTariff name="..."/>.
158 // So get a list of tariffs and filter it. 'data' param holds a pointer to 'name'.
159 std::string name(arg);
160 return proto.GetTariffs(GetTariffCallback, &name) == STG::st_ok;
161 }
162
163 bool DelTariffFunction(const SGCONF::CONFIG & config,
164                        const std::string & arg,
165                        const std::map<std::string, std::string> & /*options*/)
166 {
167 STG::SERVCONF proto(config.server.data(),
168                     config.port.data(),
169                     config.userName.data(),
170                     config.userPass.data());
171 return proto.DelTariff(arg, SimpleCallback, NULL) == STG::st_ok;
172 }
173
174 bool AddTariffFunction(const SGCONF::CONFIG & config,
175                        const std::string & arg,
176                        const std::map<std::string, std::string> & /*options*/)
177 {
178 // TODO
179 std::cerr << "Unimplemented.\n";
180 return false;
181 }
182
183 bool ChgTariffFunction(const SGCONF::CONFIG & config,
184                        const std::string & arg,
185                        const std::map<std::string, std::string> & options)
186 {
187 // TODO
188 std::cerr << "Unimplemented.\n";
189 return false;
190 }
191
192 } // namespace anonymous
193
194 void SGCONF::AppendTariffsOptionBlock(COMMANDS & commands, OPTION_BLOCKS & blocks)
195 {
196 blocks.Add("Tariff management options")
197       .Add("get-tariffs", SGCONF::MakeAPIAction(commands, GetTariffsFunction), "\tget tariff list")
198       .Add("get-tariff", SGCONF::MakeAPIAction(commands, "<name>", true, GetTariffFunction), "get tariff")
199       .Add("add-tariff", SGCONF::MakeAPIAction(commands, "<name>", true, AddTariffFunction), "add tariff")
200       .Add("del-tariff", SGCONF::MakeAPIAction(commands, "<name>", true, DelTariffFunction), "del tariff")
201       .Add("chg-tariff", SGCONF::MakeAPIAction(commands, "<name>", true, ChgTariffFunction), "change tariff");
202 }