Add functionality for additional webcontrol pages

This commit is contained in:
Mr-Dave
2025-02-24 11:49:44 -07:00
parent 702c238f44
commit cf4e903d95
10 changed files with 95 additions and 21 deletions

1
.gitignore vendored
View File

@@ -27,6 +27,7 @@ data/camera1-dist.conf
data/camera2-dist.conf
data/camera3-dist.conf
data/sound1-dist.conf
data/webcontrol/samplepage.html
#src
src/*.o

View File

@@ -23,6 +23,7 @@ SUBDIRS = src po
pkgsysconfdir = $(sysconfdir)/@PACKAGE@
libstatedir = @localstatedir@/lib/@PACKAGE@
libwebdir = @localstatedir@/lib/@PACKAGE@/webcontrol
dist_libstate_DATA = \
data/motion-dist.conf \
@@ -31,6 +32,9 @@ dist_libstate_DATA = \
data/camera3-dist.conf \
data/sound1-dist.conf
dist_libweb_DATA = \
data/webcontrol/samplepage.html
dist_man_MANS = man/motion.1
dist_doc_DATA = \
@@ -60,6 +64,7 @@ cleanall: distclean
@rm -f data/motion-dist.service data/motion-dist.conf
@rm -f data/camera1-dist.conf data/camera2-dist.conf
@rm -f data/camera3-dist.conf data/sound1-dist.conf
@rm -f data/webcontrol/samplepage.conf
###################################################################
## Testing options for maintainer

View File

@@ -662,6 +662,7 @@ AC_CONFIG_FILES([
data/sound1-dist.conf
data/motion-dist.conf
data/motion-dist.service
data/webcontrol/samplepage.html
])
AC_OUTPUT

View File

@@ -2468,7 +2468,14 @@
<h3><a name="webcontrol_html"></a> webcontrol_html</h3>
<ul>
<li> Values: String | Default: Not defined</li>
The full path and file name for a user specified html page to use as the webcontrol.
The file name for a user specified html page to use as the webcontrol. The file
must be placed in a subdirectory from the motion.conf file called webcontrol. e.g.
if the <code><small>motion.conf</small></code> file is located
at <code><small>/var/lib/motion/motion.conf</small></code>, the webcontrol
page must be located in the directory
<code><small>/var/lib/motion/webcontrol</small></code>. Additionally, any files
in the webcontrol directory with an extension of html, json, js or css will also
be available as resources to the user html page.
</ul>
<p></p>

View File

@@ -62,6 +62,19 @@ int mystrne(const char* var1, const char* var2)
return (strcmp(var1,var2) ? 1: 0);
}
/*Convert string to lower case*/
void mylower(std::string &parm)
{
if (parm.length() == 0 ) {
return;
}
std::transform(parm.begin(),parm.end(),parm.begin()
,[](unsigned char c)
{ return std::tolower(c); });
}
/* Trim whitespace from left side */
void myltrim(std::string &parm)
{

View File

@@ -94,6 +94,7 @@ struct ctx_params {
int mystrcne(const char* var1, const char* var2);
int mystreq(const char* var1, const char* var2);
int mystrne(const char* var1, const char* var2);
void mylower(std::string &parm);
void myltrim(std::string &parm);
void myrtrim(std::string &parm);
void mytrim(std::string &parm);

View File

@@ -102,7 +102,7 @@ int cls_webu_ans::parseurl()
size_t pos_slash1, pos_slash2, baselen;
/* Example: /camid/cmd1/cmd2/cmd3 */
uri_camid = "";
uri_cmd0 = "";
uri_cmd1 = "";
uri_cmd2 = "";
uri_cmd3 = "";
@@ -149,9 +149,9 @@ int cls_webu_ans::parseurl()
pos_slash1 = url.find("/", baselen+1);
if (pos_slash1 != std::string::npos) {
uri_camid = url.substr(baselen+1, pos_slash1-baselen- 1);
uri_cmd0 = url.substr(baselen+1, pos_slash1-baselen- 1);
} else {
uri_camid = url.substr(baselen+1);
uri_cmd0 = url.substr(baselen+1);
return 0;
}
@@ -201,22 +201,22 @@ void cls_webu_ans::parms_edit()
int indx, is_nbr;
if (parseurl() != 0) {
uri_camid = "";
uri_cmd0 = "";
uri_cmd1 = "";
uri_cmd2 = "";
uri_cmd3 = "";
url = "";
}
if (uri_camid.length() > 0) {
if (uri_cmd0.length() > 0) {
is_nbr = true;
for (indx=0; indx < (int)uri_camid.length(); indx++) {
if ((uri_camid[(uint)indx] > '9') || (uri_camid[(uint)indx] < '0')) {
for (indx=0; indx < (int)uri_cmd0.length(); indx++) {
if ((uri_cmd0[(uint)indx] > '9') || (uri_cmd0[(uint)indx] < '0')) {
is_nbr = false;
}
}
if (is_nbr) {
device_id = atoi(uri_camid.c_str());
device_id = atoi(uri_cmd0.c_str());
}
}
@@ -228,10 +228,10 @@ void cls_webu_ans::parms_edit()
}
MOTION_LOG(DBG, TYPE_STREAM, NO_ERRNO
, "camid: >%s< camindx: >%d< cmd1: >%s< cmd2: >%s< cmd3: >%s<"
, uri_camid.c_str(), camindx
, uri_cmd1.c_str(), uri_cmd2.c_str()
, uri_cmd3.c_str());
, "cmd0: >%s< cmd1: >%s< cmd2: >%s< cmd3: >%s< camindx: >%d< "
, uri_cmd0.c_str(), uri_cmd1.c_str()
, uri_cmd2.c_str(), uri_cmd3.c_str()
, camindx );
}
@@ -951,7 +951,7 @@ cls_webu_ans::cls_webu_ans(cls_motapp *p_app, const char *uri)
char *tmplang;
url = "";
uri_camid = "";
uri_cmd0 = "";
uri_cmd1 = "";
uri_cmd2 = "";
uri_cmd3 = "";

View File

@@ -33,10 +33,10 @@
std::string lang; /* Two character abbreviation for locale language*/
std::string url; /* The URL sent from the client */
std::string uri_camid; /* Parsed camera number from the url eg /camid/cmd1/cmd2/cmd3 */
std::string uri_cmd1; /* Parsed command1 from the url eg /camid/cmd1/cmd2/cmd3 */
std::string uri_cmd2; /* Parsed command2 from the url eg /camid/cmd1/cmd2/cmd3 */
std::string uri_cmd3; /* Parsed command3 from the url eg /camid/cmd1/cmd2/cmd3 */
std::string uri_cmd0; /* Parsed command1 from the url eg /cmd0/cmd1/cmd2/cmd3 */
std::string uri_cmd1; /* Parsed command1 from the url eg /cmd0/cmd1/cmd2/cmd3 */
std::string uri_cmd2; /* Parsed command2 from the url eg /cmd0/cmd1/cmd2/cmd3 */
std::string uri_cmd3; /* Parsed command3 from the url eg /cmd0/cmd1/cmd2/cmd3 */
enum WEBUI_RESP resp_type; /* indicator for the type of response to provide. */
std::string resp_page; /* The response that will be sent */

View File

@@ -1596,20 +1596,66 @@ void cls_webu_html::default_page()
void cls_webu_html::user_page()
{
char response[PATH_MAX];
std::string fname, ext;
size_t pos;
FILE *fp = NULL;
webua->resp_page = "";
fp = myfopen(app->cfg->webcontrol_html.c_str(), "re");
pos = app->cfg->conf_filename.find("/",0);
if (pos == std::string::npos) {
MOTION_LOG(ERR, TYPE_STREAM, NO_ERRNO
, _("Unable to determine base path for: %s")
, app->cfg->conf_filename.c_str());
return;
}
fname = app->cfg->conf_filename.substr(0,
app->cfg->conf_filename.find_last_of("/"));
fname += "/webcontrol";
if (webua->uri_cmd0 == "") {
fname += "/"+app->cfg->webcontrol_html;
} else {
fname += webua->url;
}
pos = fname.find(".", 0);
if (pos == std::string::npos) {
ext = "";
} else {
ext = fname.substr(fname.find_last_of(".")+1);
}
mylower(ext);
if (ext == "json") {
webua->resp_type = WEBUI_RESP_JSON;
} else if ((ext == "js") || (ext == "css")) {
webua->resp_type = WEBUI_RESP_TEXT;
} else if (ext == "html") {
webua->resp_type = WEBUI_RESP_HTML;
} else {
MOTION_LOG(ERR, TYPE_STREAM, NO_ERRNO
, _("Invalid file requested: %s")
, fname.c_str());
return;
}
MOTION_LOG(DBG, TYPE_STREAM, NO_ERRNO
, _("Retrieving file: %s type/extension: %d/%s")
, fname.c_str(), webua->resp_type, ext.c_str());
fp = myfopen(fname.c_str(), "re");
if (fp == NULL) {
MOTION_LOG(ERR, TYPE_STREAM, NO_ERRNO
, _("Invalid user html file: %s")
, app->cfg->webcontrol_html.c_str());
, _("Invalid user requested file: %s")
, fname.c_str());
return;
} else {
while (fgets(response, PATH_MAX-1, fp)) {
webua->resp_page += response;
}
myfclose(fp);
}
}
void cls_webu_html::main()