]> git.vomp.tv Git - jsonserver.git/blob - jsonserver.c
JSON: Switch from StyledWriter to StreamWriterBuilder
[jsonserver.git] / jsonserver.c
1 /*
2  * jsonserver.c: A plugin for the Video Disk Recorder
3  *
4  * See the README file for copyright information and how to reach the author.
5  *
6  */
7 // Log docs: https://github.com/gabime/spdlog
8 #include <spdlog/spdlog.h>
9 #if __has_include(<spdlog/sinks/basic_file_sink.h>)
10 #include <spdlog/sinks/basic_file_sink.h>
11 #endif
12 namespace spd = spdlog;
13 /*
14 trace
15 debug
16 info
17 warn
18 error
19 critical
20 */
21
22 #include <vdr/plugin.h>
23
24 #if APIVERSNUM < 20102
25 #error jsonserver plugin requires VDR API version > 20101
26 #endif
27
28 #include <stdio.h>
29
30 // Config docs: http://www.hyperrealm.com/libconfig/libconfig_manual.html#The-C_002b_002b-API
31 #include <libconfig.h++>
32
33 #include "httpdclient.h"
34
35 static const char *VERSION        = "0.0.1";
36 static const char *DESCRIPTION    = "JSON data server plugin for VDR";
37 static const char *MAINMENUENTRY  = "Jsonserver";
38
39 class cPluginJsonserver : public cPlugin {
40 private:
41   // Add any member variables or functions you may need here.
42   std::shared_ptr<spd::logger> logger;
43   libconfig::Config config;
44 public:
45   cPluginJsonserver(void);
46   virtual ~cPluginJsonserver();
47   virtual const char *Version(void) { return VERSION; }
48   virtual const char *Description(void) { return DESCRIPTION; }
49   virtual const char *CommandLineHelp(void);
50   virtual bool ProcessArgs(int argc, char *argv[]);
51   virtual bool Initialize(void);
52   virtual bool Start(void);
53   virtual void Stop(void);
54   virtual void Housekeeping(void);
55   virtual void MainThreadHook(void);
56   virtual cString Active(void);
57   virtual time_t WakeupTime(void);
58   virtual const char *MainMenuEntry(void) { return MAINMENUENTRY; }
59   virtual cOsdObject *MainMenuAction(void);
60   virtual cMenuSetupPage *SetupMenu(void);
61   virtual bool SetupParse(const char *Name, const char *Value);
62   virtual bool Service(const char *Id, void *Data = NULL);
63   virtual const char **SVDRPHelpPages(void);
64   virtual cString SVDRPCommand(const char *Command, const char *Option, int &ReplyCode);
65   };
66
67 cPluginJsonserver::cPluginJsonserver(void)
68 {
69   // Initialize any member variables here.
70   // DON'T DO ANYTHING ELSE THAT MAY HAVE SIDE EFFECTS, REQUIRE GLOBAL
71   // VDR OBJECTS TO EXIST OR PRODUCE ANY OUTPUT!
72 }
73
74 cPluginJsonserver::~cPluginJsonserver()
75 {
76   // Clean up after yourself!
77   logger.reset();
78 }
79
80 const char *cPluginJsonserver::CommandLineHelp(void)
81 {
82   // Return a string that describes all known command line options.
83   return NULL;
84 }
85
86 bool cPluginJsonserver::ProcessArgs(int argc, char *argv[])
87 {
88   // Implement command line argument processing here if applicable.
89   return true;
90 }
91
92 bool cPluginJsonserver::Initialize(void)
93 {
94   // Initialize any background activities the plugin shall perform.
95   return true;
96 }
97
98 bool cPluginJsonserver::Start(void)
99 {
100   // Start any background activities the plugin shall perform.
101   const char* configDir = cPlugin::ConfigDirectory("jsonserver");
102   if (!configDir)
103   {
104     dsyslog("jsonserver: Error: Could not get config dir from VDR");
105     return false;
106   }
107
108   std::string configFile(std::string(configDir) + std::string("/server.conf"));
109   dsyslog("%s", configFile.c_str());
110   try
111   {
112     config.readFile(configFile.c_str());
113   }
114   catch (const libconfig::FileIOException &fioex)
115   {
116     dsyslog("jsonserver: Failed to read config file");
117     return false;
118   }
119   catch(const libconfig::ParseException &pex)
120   {
121     dsyslog("jsonserver: Config parse error at %s: %i - %s", pex.getFile(), pex.getLine(), pex.getError());
122     return false;
123   }
124
125   std::string cfgLogFilename;
126   if (config.lookupValue("log-file", cfgLogFilename))
127   {
128     try
129     {
130       logger = spd::basic_logger_mt("jsonserver_spdlog", cfgLogFilename);
131       if (!logger)
132       {
133         dsyslog("jsonserver: Failed to initialise log object - null");
134         return false;
135       }
136     }
137     catch (const spd::spdlog_ex& ex)
138     {
139       dsyslog("jsonserver: Failed to initialise log object: %s", ex.what());
140     }
141
142     logger->set_pattern("[%Y-%m-%d %T.%f] [%t] [%l] %v");
143     logger->set_level(spd::level::trace); //Set global log level to info
144     logger->flush_on(spd::level::debug); // FIXME Change this!!
145
146     logger->info("Main: Logging started");
147   }
148   else
149   {
150     dsyslog("jsonserver: Logging disabled");
151   }
152
153   std::string cfgDocRoot;
154   if (!config.lookupValue("doc-root", cfgDocRoot))
155   {
156     logger->critical("Main: Failed to load doc-root from config");
157     dsyslog("jsonserver: Could not load JS App Dir from plugin config file");
158     logger.reset();
159     return false;
160   }
161
162   int cfgPort;
163   if (!config.lookupValue("http-port", cfgPort))
164   {
165     logger->critical("Main: Failed to load http-port from config");
166     dsyslog("jsonserver: Could not load http-port from plugin config file");
167     logger.reset();
168     return false;
169   }
170
171   if (!HTTPDClient::StartServer(cfgDocRoot, cfgPort, configDir))
172   {
173     logger->critical("Main: Failed to start MHD");
174     dsyslog("jsonserver: Failed to start MHD");
175     logger.reset();
176     return false;
177   }
178
179   return true;
180 }
181
182 void cPluginJsonserver::Stop(void)
183 {
184   // Stop any background activities the plugin is performing.
185   HTTPDClient::StopServer();
186 }
187
188 void cPluginJsonserver::Housekeeping(void)
189 {
190   // Perform any cleanup or other regular tasks.
191 }
192
193 void cPluginJsonserver::MainThreadHook(void)
194 {
195   // Perform actions in the context of the main program thread.
196   // WARNING: Use with great care - see PLUGINS.html!
197 }
198
199 cString cPluginJsonserver::Active(void)
200 {
201   // Return a message string if shutdown should be postponed
202   return NULL;
203 }
204
205 time_t cPluginJsonserver::WakeupTime(void)
206 {
207   // Return custom wakeup time for shutdown script
208   return 0;
209 }
210
211 cOsdObject *cPluginJsonserver::MainMenuAction(void)
212 {
213   // Perform the action when selected from the main VDR menu.
214   return NULL;
215 }
216
217 cMenuSetupPage *cPluginJsonserver::SetupMenu(void)
218 {
219   // Return a setup menu in case the plugin supports one.
220   return NULL;
221 }
222
223 bool cPluginJsonserver::SetupParse(const char *Name, const char *Value)
224 {
225   // Parse your own setup parameters and store their values.
226   return false;
227 }
228
229 bool cPluginJsonserver::Service(const char *Id, void *Data)
230 {
231   // Handle custom service requests from other plugins
232   return false;
233 }
234
235 const char **cPluginJsonserver::SVDRPHelpPages(void)
236 {
237   // Return help text for SVDRP commands this plugin implements
238   return NULL;
239 }
240
241 cString cPluginJsonserver::SVDRPCommand(const char *Command, const char *Option, int &ReplyCode)
242 {
243   // Process SVDRP commands this plugin implements
244   return NULL;
245 }
246
247 VDRPLUGINCREATOR(cPluginJsonserver); // Don't touch this!