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