Hello community,

here is the log from the commit of package libyui-rest-api for openSUSE:Factory 
checked in at 2020-06-10 00:39:21
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libyui-rest-api (Old)
 and      /work/SRC/openSUSE:Factory/.libyui-rest-api.new.3606 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libyui-rest-api"

Wed Jun 10 00:39:21 2020 rev:4 rq:812662 version:0.4.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/libyui-rest-api/libyui-rest-api.changes  
2019-12-25 10:54:19.705620406 +0100
+++ 
/work/SRC/openSUSE:Factory/.libyui-rest-api.new.3606/libyui-rest-api.changes    
    2020-06-10 00:39:39.381594994 +0200
@@ -1,0 +2,15 @@
+Thu Jun  4 12:21:23 UTC 2020 - Stefan Hundhammer <[email protected]>
+
+- Use new parent lib SO version libyui.so.12 (bsc#1172513)
+- 0.4.1 
+
+-------------------------------------------------------------------
+Wed Feb  5 12:09:35 UTC 2020 - Oleksandr Orlov <[email protected]>
+
+- Replace hard-coded HTML documentation with the url to the actual
+  documentation in project repo
+- Add "/version" endpoint to access to API version
+- Use /v1/ prefix in URL path while accessing resources
+- 0.4.0
+
+-------------------------------------------------------------------

Old:
----
  libyui-rest-api-0.3.0.tar.bz2

New:
----
  libyui-rest-api-0.4.1.tar.bz2

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ libyui-rest-api.spec ++++++
--- /var/tmp/diff_new_pack.yki3Fk/_old  2020-06-10 00:39:40.573598120 +0200
+++ /var/tmp/diff_new_pack.yki3Fk/_new  2020-06-10 00:39:40.577598130 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package libyui-rest-api
 #
-# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2020 SUSE LINUX GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -16,12 +16,12 @@
 #
 
 
-%define so_version 11
+%define so_version 12
 %define bin_name %{name}%{so_version}
-%define libyui_devel_version libyui-devel >= 3.8.0
+%define libyui_devel_version libyui-devel >= 3.10.0
 
 Name:           libyui-rest-api
-Version:        0.3.0
+Version:        0.4.1
 Release:        0
 Summary:        Libyui - REST API plugin, the shared part
 License:        LGPL-2.1-only OR LGPL-3.0-only

++++++ libyui-rest-api-0.3.0.tar.bz2 -> libyui-rest-api-0.4.1.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libyui-rest-api-0.3.0/API_v1.md 
new/libyui-rest-api-0.4.1/API_v1.md
--- old/libyui-rest-api-0.3.0/API_v1.md 1970-01-01 01:00:00.000000000 +0100
+++ new/libyui-rest-api-0.4.1/API_v1.md 2020-06-08 17:07:52.000000000 +0200
@@ -0,0 +1,161 @@
+# LibYUI REST API v1
+
+This is the specification of the version 1 of the API.
+
+## API Documentation
+
+### API Version
+
+Request: `GET /version`
+
+#### Description
+
+Get the application and UI generic properties like text or graphical mode,
+dialog size, screen size and supported UI features.
+
+#### Response
+
+JSON format
+
+```json
+{
+  "api_version" : "v1"
+}
+```
+
+The `api_version` value defines the version of the API. It is used in the URL
+as the path prefix.
+
+##### Examples
+
+```
+curl http://localhost:9999/version
+```
+---
+
+### Application Data
+
+Request: `GET /v1/application`
+
+#### Description
+
+Get the application and UI generic properties like text or graphical mode,
+dialog size, screen size and supported UI features.
+
+#### Response
+
+JSON format
+
+##### Examples
+
+```
+curl http://localhost:9999/v1/application
+```
+---
+
+### Dump Whole Dialog
+ 
+ Request: `GET /v1/dialog`
+
+#### Description
+
+Get the complete dialog structure in the JSON format. The result contains
+a nested structure exactly following the structure of the current dialog.
+
+#### Response
+
+JSON format
+
+##### Examples
+
+```
+curl http://localhost:9999/v1/dialog
+```
+
+---
+
+### Read Only Specific Widgets
+
+Request: `GET /v1/widgets`
+
+#### Description
+
+Return only the selected widgets (in JSON format). The result is a flat list
+(no nested structures).
+
+#### Parameters
+
+Filter widgets:
+
+- **id** - the widget ID serialized as string, might include special characters
+  like backtick (\`)
+- **label** - widget label as currently displayed (i.e. translated!)
+- **type** - the widget type
+
+#### Response
+
+JSON format
+
+#### Examples
+
+```
+curl 'http://localhost:9999/v1/widgets?label=Next
+curl 'http://localhost:9999/v1/widgets?id=next
+curl 'http://localhost:9999/v1/widgets?type=YCheckBox
+```
+
+---
+
+### Change Widgets, Do an Action</h3>
+
+Request: `POST /v1/widgets`
+
+#### Description
+
+Do an action with specified widgets.
+
+#### Parameters
+
+Filter the widgets, one of:
+
+- **id** - widget ID serialized as string, might include special characters
+  like backtick (\`)
+- **label** - widget label as currently displayed (i.e. translated!)
+- **type** - type of the widget
+
+Then specify the action:
+
+- **action** - the action to do
+- **value** (optional) - new value or a parameter of the action
+- **column** (optional) - column id when selecting item in the table
+
+Supported actions:
+
+- **press** - to press the button
+- **check** | **uncheck**  | **toggle** - check, uncheck or toggle checkbox
+- **enter_text** - set text in the field, the text is passed in the
+  *value* parameter
+- **switch_radio** - activate radio button
+- **select** - select value in the combobox, row in the table or node in the
+  tree, requires *value*parameter
+  - In case of table: select row in the table with given value. If
+        *column* parameter is not provided, the first column will be used.  
+  - In case of tree: select node in the tree. Use `|` as a delimiter for
+        the child nodes.
+
+#### Response
+
+JSON format
+
+#### Examples
+
+```shell
+# press the "next" button
+curl -X POST 'http://localhost:9999/v1/widgets?id=next&action=press'
+# set value "test" for the InputField with label "Description"
+curl -X POST 
'http://localhost:9999/v1/widgets?label=Description&action=enter_text&value=test'
+# select row with "test" cell value in the 2-nd column (counting from zero) in 
table with id "names"
+curl -X POST 
'http://localhost:9999/v1/widgets?id=names&action=select&value=test&column=2'
+# select tree item with in tree with id "files"
+curl -X POST 
'http://localhost:9999/v1/widgets?id=files&action=select&value=root|subnode|subnode'
+```
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libyui-rest-api-0.3.0/SOURCECONF.cmake 
new/libyui-rest-api-0.4.1/SOURCECONF.cmake
--- old/libyui-rest-api-0.3.0/SOURCECONF.cmake  2019-12-10 17:02:47.000000000 
+0100
+++ new/libyui-rest-api-0.4.1/SOURCECONF.cmake  2020-06-08 17:07:52.000000000 
+0200
@@ -3,6 +3,7 @@
  YHttpHandler.cc
  YHttpDialogHandler.cc
  YHttpRootHandler.cc
+ YHttpVersionHandler.cc
  YHttpAppHandler.cc
  YHttpWidgetsHandler.cc
  YHttpWidgetsActionHandler.cc
@@ -17,6 +18,7 @@
  YHttpHandler.h
  YHttpDialogHandler.h
  YHttpRootHandler.h
+ YHttpVersionHandler.h
  YHttpAppHandler.h
  YHttpWidgetsHandler.h
  YHttpWidgetsActionHandler.h
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libyui-rest-api-0.3.0/VERSION.cmake 
new/libyui-rest-api-0.4.1/VERSION.cmake
--- old/libyui-rest-api-0.3.0/VERSION.cmake     2019-12-10 17:02:47.000000000 
+0100
+++ new/libyui-rest-api-0.4.1/VERSION.cmake     2020-06-08 17:07:52.000000000 
+0200
@@ -1,6 +1,6 @@
 SET( VERSION_MAJOR "0")
-SET( VERSION_MINOR "3" )
-SET( VERSION_PATCH "0" )
+SET( VERSION_MINOR "4" )
+SET( VERSION_PATCH "1" )
 SET( VERSION 
"${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}${GIT_SHA1_VERSION}" )
 
 ##### This is need for the libyui core, ONLY.
@@ -8,7 +8,7 @@
 # Currently you must also change so_version in libyui.spec
 # *and also in **all** other* libyui-*.spec files in the other repositories.
 # Yes, such a design is suboptimal.
-SET( SONAME_MAJOR "11" )
+SET( SONAME_MAJOR "12" )
 SET( SONAME_MINOR "0" )
 SET( SONAME_PATCH "0" )
 SET( SONAME "${SONAME_MAJOR}.${SONAME_MINOR}.${SONAME_PATCH}" )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libyui-rest-api-0.3.0/package/libyui-rest-api.changes 
new/libyui-rest-api-0.4.1/package/libyui-rest-api.changes
--- old/libyui-rest-api-0.3.0/package/libyui-rest-api.changes   2019-12-10 
17:02:47.000000000 +0100
+++ new/libyui-rest-api-0.4.1/package/libyui-rest-api.changes   2020-06-08 
17:07:52.000000000 +0200
@@ -1,4 +1,19 @@
 -------------------------------------------------------------------
+Thu Jun  4 12:21:23 UTC 2020 - Stefan Hundhammer <[email protected]>
+
+- Use new parent lib SO version libyui.so.12 (bsc#1172513)
+- 0.4.1 
+
+-------------------------------------------------------------------
+Wed Feb  5 12:09:35 UTC 2020 - Oleksandr Orlov <[email protected]>
+
+- Replace hard-coded HTML documentation with the url to the actual
+  documentation in project repo
+- Add "/version" endpoint to access to API version
+- Use /v1/ prefix in URL path while accessing resources
+- 0.4.0
+
+-------------------------------------------------------------------
 Fri Nov 29 14:44:10 UTC 2019 - Rodion Iafarov <[email protected]>
 
 - Add support to operate on many widgets with rest-api (bsc#1132247)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libyui-rest-api-0.3.0/package/libyui-rest-api.spec 
new/libyui-rest-api-0.4.1/package/libyui-rest-api.spec
--- old/libyui-rest-api-0.3.0/package/libyui-rest-api.spec      2019-12-10 
17:02:47.000000000 +0100
+++ new/libyui-rest-api-0.4.1/package/libyui-rest-api.spec      2020-06-08 
17:07:52.000000000 +0200
@@ -16,12 +16,12 @@
 #
 
 
-%define so_version 11
+%define so_version 12
 %define bin_name %{name}%{so_version}
-%define libyui_devel_version libyui-devel >= 3.8.0
+%define libyui_devel_version libyui-devel >= 3.10.0
 
 Name:           libyui-rest-api
-Version:        0.3.0
+Version:        0.4.1
 Release:        0
 Summary:        Libyui - REST API plugin, the shared part
 License:        LGPL-2.1-only OR LGPL-3.0-only
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libyui-rest-api-0.3.0/src/YHttpAppHandler.cc 
new/libyui-rest-api-0.4.1/src/YHttpAppHandler.cc
--- old/libyui-rest-api-0.3.0/src/YHttpAppHandler.cc    2019-12-10 
17:02:47.000000000 +0100
+++ new/libyui-rest-api-0.4.1/src/YHttpAppHandler.cc    2020-06-08 
17:07:52.000000000 +0200
@@ -24,9 +24,10 @@
 #include <microhttpd.h>
 #include <json/json.h>
 
-void YHttpAppHandler::body(struct MHD_Connection* connection,
+void YHttpAppHandler::process_request(struct MHD_Connection* connection,
     const char* url, const char* method, const char* upload_data,
-    size_t* upload_data_size, std::ostream& body, bool *redraw)
+    size_t* upload_data_size, std::ostream& body, int& error_code,
+    std::string& content_encoding, bool *redraw)
 {
     Json::Value info;
     YApplication *app = YUI::app();
@@ -64,14 +65,6 @@
     }
     
     YJsonSerializer::save(info, body);
-}
-
-std::string YHttpAppHandler::contentEncoding()
-{
-    return "application/json";
-}
-
-int YHttpAppHandler::errorCode()
-{
-    return MHD_HTTP_OK;
+    error_code = MHD_HTTP_OK;
+    content_encoding = "application/json";
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libyui-rest-api-0.3.0/src/YHttpAppHandler.h 
new/libyui-rest-api-0.4.1/src/YHttpAppHandler.h
--- old/libyui-rest-api-0.3.0/src/YHttpAppHandler.h     2019-12-10 
17:02:47.000000000 +0100
+++ new/libyui-rest-api-0.4.1/src/YHttpAppHandler.h     2020-06-08 
17:07:52.000000000 +0200
@@ -29,14 +29,10 @@
 
 protected:
 
-    virtual void body(struct MHD_Connection* connection,
+    virtual void process_request(struct MHD_Connection* connection,
         const char* url, const char* method, const char* upload_data,
-        size_t* upload_data_size, std::ostream& body, bool *redraw);
-
-    virtual int errorCode();
-
-    virtual std::string contentEncoding();
-
+        size_t* upload_data_size, std::ostream& body, int& error_code,
+        std::string& content_encoding, bool *redraw);
 };
 
 #endif // YHttpAppHandler_h
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libyui-rest-api-0.3.0/src/YHttpDialogHandler.cc 
new/libyui-rest-api-0.4.1/src/YHttpDialogHandler.cc
--- old/libyui-rest-api-0.3.0/src/YHttpDialogHandler.cc 2019-12-10 
17:02:47.000000000 +0100
+++ new/libyui-rest-api-0.4.1/src/YHttpDialogHandler.cc 2020-06-08 
17:07:52.000000000 +0200
@@ -19,21 +19,19 @@
 #include "YHttpDialogHandler.h"
 #include <microhttpd.h>
 
-void YHttpDialogHandler::body(struct MHD_Connection* connection,
+void YHttpDialogHandler::process_request(struct MHD_Connection* connection,
     const char* url, const char* method, const char* upload_data,
-    size_t* upload_data_size, std::ostream& body, bool *redraw)
+    size_t* upload_data_size, std::ostream& body, int& error_code,
+    std::string& content_encoding, bool *redraw)
 {
     if (auto dialog = YDialog::topmostDialog(false))  {
         YJsonSerializer::serialize(dialog, body);
-        _error_code = MHD_HTTP_OK;
+        error_code = MHD_HTTP_OK;
     }
     else {
         body << "{ \"error\" : \"No dialog is open\" }" << std::endl;
-        _error_code = MHD_HTTP_NOT_FOUND;
+        error_code = MHD_HTTP_NOT_FOUND;
     }
-}
 
-std::string YHttpDialogHandler::contentEncoding()
-{
-    return "application/json";
-}
\ No newline at end of file
+    content_encoding = "application/json";
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libyui-rest-api-0.3.0/src/YHttpDialogHandler.h 
new/libyui-rest-api-0.4.1/src/YHttpDialogHandler.h
--- old/libyui-rest-api-0.3.0/src/YHttpDialogHandler.h  2019-12-10 
17:02:47.000000000 +0100
+++ new/libyui-rest-api-0.4.1/src/YHttpDialogHandler.h  2020-06-08 
17:07:52.000000000 +0200
@@ -29,17 +29,11 @@
 
 protected:
 
-    virtual void body(struct MHD_Connection* connection,
+    virtual void process_request(struct MHD_Connection* connection,
         const char* url, const char* method, const char* upload_data,
-        size_t* upload_data_size, std::ostream& body, bool *redraw);
+        size_t* upload_data_size, std::ostream& body, int& error_code,
+        std::string& content_encoding, bool *redraw);
 
-    virtual int errorCode() {return _error_code;}
-
-    virtual std::string contentEncoding();
-
-private:
-
-    int _error_code;
 };
 
 #endif // YHttpDialogHandler_h
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libyui-rest-api-0.3.0/src/YHttpHandler.cc 
new/libyui-rest-api-0.4.1/src/YHttpHandler.cc
--- old/libyui-rest-api-0.3.0/src/YHttpHandler.cc       2019-12-10 
17:02:47.000000000 +0100
+++ new/libyui-rest-api-0.4.1/src/YHttpHandler.cc       2020-06-08 
17:07:52.000000000 +0200
@@ -27,21 +27,23 @@
         size_t* upload_data_size, bool *redraw)
 {
     std::ostringstream body_s;
-    body(connection, url, method, upload_data, upload_data_size, body_s, 
redraw);
-    std::string body_str = body_s.str();
+    std::string encoding;
+    int error_code;
+
+    process_request(connection, url, method, upload_data, upload_data_size,
+      body_s, error_code, encoding, redraw);
 
+    std::string body_str = body_s.str();
     struct MHD_Response *response = MHD_create_response_from_buffer 
(body_str.length(),
                      (void *) body_str.c_str(), MHD_RESPMEM_MUST_COPY);
 
-    const std::string encoding = contentEncoding();
-
     if (!encoding.empty())
         MHD_add_response_header(response, MHD_HTTP_HEADER_CONTENT_ENCODING, 
encoding.c_str());
 
-    yuiMilestone() << "Sending response: code: " << errorCode() << ", body 
size: " << body_str.length()
+    yuiMilestone() << "Sending response: code: " << error_code << ", body 
size: " << body_str.length()
       << ", content type: " << encoding << std::endl;
 
-    int ret = MHD_queue_response(connection, errorCode(), response);
+    int ret = MHD_queue_response(connection, error_code, response);
     MHD_destroy_response (response);
     return ret;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libyui-rest-api-0.3.0/src/YHttpHandler.h 
new/libyui-rest-api-0.4.1/src/YHttpHandler.h
--- old/libyui-rest-api-0.3.0/src/YHttpHandler.h        2019-12-10 
17:02:47.000000000 +0100
+++ new/libyui-rest-api-0.4.1/src/YHttpHandler.h        2020-06-08 
17:07:52.000000000 +0200
@@ -37,13 +37,10 @@
 
 protected:
 
-    virtual void body(struct MHD_Connection* connection,
+    virtual void process_request(struct MHD_Connection* connection,
         const char* url, const char* method, const char* upload_data,
-        size_t* upload_data_size, std::ostream& body,  bool *redraw) = 0;
-
-    virtual int errorCode() = 0;
-
-    virtual std::string contentEncoding() = 0;
+        size_t* upload_data_size, std::ostream& body, int& error_code,
+        std::string& content_encoding, bool *redraw) = 0;
 };
 
 #endif // YHttpHandler_h
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libyui-rest-api-0.3.0/src/YHttpRootHandler.cc 
new/libyui-rest-api-0.4.1/src/YHttpRootHandler.cc
--- old/libyui-rest-api-0.3.0/src/YHttpRootHandler.cc   2019-12-10 
17:02:47.000000000 +0100
+++ new/libyui-rest-api-0.4.1/src/YHttpRootHandler.cc   2020-06-08 
17:07:52.000000000 +0200
@@ -16,131 +16,62 @@
 
 #include "YHttpRootHandler.h"
 #include "YHttpServer.h"
+#include "YJsonSerializer.h"
 
 #include <microhttpd.h>
 #include <string>
+#include <cstring>
 #include <boost/algorithm/string/replace.hpp>
+#include <json/json.h>
 
-void YHttpRootHandler::body(struct MHD_Connection* connection,
+#define YUILogComponent "rest-api"
+#include "YUILog.h"
+
+bool accepts_html(struct MHD_Connection *connection);
+
+const std::string YHttpRootHandler::documentation_url = 
"https://github.com/libyui/libyui-rest-api/blob/master/API_v1.md";;
+
+void YHttpRootHandler::process_request(struct MHD_Connection* connection,
     const char* url, const char* method, const char* upload_data,
-    size_t* upload_data_size, std::ostream& body, bool *redraw)
+    size_t* upload_data_size, std::ostream& body, int& error_code,
+    std::string& content_encoding, bool *redraw)
 {
-    // TODO: save this to a standalone HTML file, editing HTML in a C string
-    // literal is cumbersome, use bin2c or something like that for converting
-    // to a C source file...
-    std::string help =
+    if (accepts_html(connection))
+    {
+        body <<
 "<html>"
 "  <head><title>LibYUI Embedded Webserver</title></head>"
 "  <body>"
-"    <h1>LibYUI Embedded Webserver</h1>"
-"    <p>This webserver provides a REST API for the LibYUI application.</p>"
-"      <p>It can be used for testing and controlling the application in 
automated tests.</p>"
-"      <br>"
-"      <h2>Short Documentation</h2>"
-"      <h3>Application</h3>"
-"      <p>Request: GET <a href='/application'>/application</a></p>"
-"      <h4>Description</h4>"
-"      <p>Get the application and UI generic properties like text or graphical 
mode,"
-"      dialog size, screen size and supported UI featues.</p>"
-"      <h4>Response</h4>"
-"      <p>JSON format</p>"
-"      <h4>Examples</h4>"
-"      <p>"
-"        <pre>  curl http://localhost:@port@/application</pre>"
-"      </p>"
-"      <hr>"
-"      <h3>Dump Whole Dialog</h3>"
-"      <p>Request: GET <a href='/dialog'>/dialog</a></p>"
-"      <h4>Description</h4>"
-"      <p>Get the complete dialog structure in the JSON format."
-"      The result contains a nested structure exactly following the structure 
of the current dialog.</p>"
-"      <h4>Response</h4>"
-"      <p>JSON format</p>"
-"      <h4>Examples</h4>"
-"      <p>"
-"        <pre>  curl http://localhost:@port@/dialog</pre>"
-"      </p>"
-
-"      <hr>"
-"      <h3>Read Specific Widgets</h3>"
-"      <p>Request: GET <a href='/widgets'>/widgets</a></p>"
-"      <h4>Description</h4>"
-"      <p>Return only the selected widgets (in JSON format). The result is"
-"        a flat list (no nested structures).</p>"
-"      <h4>Parameters</h4>"
-"      <p>Filter widgets:"
-"        <ul>"
-"          <li><b>id</b> - widget ID serialized as string, might include 
special characters like backtick (`)</li>"
-"          <li><b>label</b> - widget label as currently displayed (i.e. 
translated!) </li>"
-"          <li><b>type</b> - widget type</li>"
-"        </ul>"
-"      </p>"
-"      <h4>Response</h4>"
-"      <p>JSON format</p>"
-"      <h4>Examples</h4>"
-"      <p>"
-"        <pre>  curl 'http://localhost:@port@/widgets?id=`next'</pre>"
-"        <pre>  curl 'http://localhost:@port@/widgets?label=Next'</pre>"
-"        <pre>  curl 'http://localhost:@port@/widgets?type=YCheckBox'</pre>"
-"      </p>"
-
-"      <hr>"
-"      <h3>Change Widgets, Do an Action</h3>"
-"      <p>Request: POST /widgets</p>"
-"      <h4>Description</h4>"
-"      <p>Do an action with specified widgets.</p>"
-"      <h4>Parameters</h4>"
-"      <p>Filter the widgets, one of:"
-"        <ul>"
-"          <li><b>id</b> - widget ID serialized as string, might include 
special characters like backtick (`)</li>"
-"          <li><b>label</b> - widget label as currently displayed (i.e. 
translated!) </li>"
-"          <li><b>type</b> - widget type</li>"
-"        </ul>"
-" Then specify the action:"
-"        <ul>"
-"          <li><b>action</b> - action to do</li>"
-"          <li><b>value</b> (optional) - new value or a parameter of the 
action</li>"
-"          <li><b>column</b> (optional) - column id when selecting item in the 
table</li>"
-"        </ul>"
-"      </p>"
-" Supported actions:"
-"        <ul>"
-"          <li><b>press</b> - to press the button</li>"
-"          <li><b>check</b>|<b>uncheck</b>|<b>toggle</b> - check, uncheck or 
toggle checkbox</li>"
-"          <li><b>enter_text</b> - set text in the field, requires 
<b>value</b> parameter</li>"
-"          <li><b>switch_radio</b> - activate radio button</li>"
-"          <li><b>select</b> - select value in the combobox, row in the table 
or node in the tree, requires <b>value</b> parameter<br />"
-"                 In case of table: select row in the table with given value. 
If <b>column</b> parameters is not provided, first column will be used. <br />"
-"                 In case of tree: select node in the tree. Use <b>'|'</b> as 
delimiter for child nodes.</li>"
-"        </ul>"
-"      </p>"
-"      <h4>Response</h4>"
-"      <p>JSON format</p>"
-"      <h4>Examples</h4>"
-"      <p>"
-"        <pre>  # press the `next button\n"
-"  curl -X POST 'http://localhost:@port@/widgets?id=`next&action=press'</pre>"
-"        <pre>  # set value \"test\" for the InputField with label 
\"Description\"\n"
-"  curl -X POST 
'http://localhost:@port@/widgets?label=Description&action=enter_text&value=test'</pre>"
-"        <pre>  # select row with \"test\" cell value in the 2-nd column 
(counting from zero) in table with id \"names\"\n"
-"  curl -X POST 
'http://localhost:@port@/widgets?id=names&action=select&value=test&column=2'</pre>"
-"        <pre>  # select tree item with in tree with id \"files\"\n"
-"  curl -X POST 
'http://localhost:@port@/widgets?id=files&action=select&value=root|subnode|subnode'</pre>"
-"      </p>"
+"    <h2>The Libyui REST API Documentation</h2>"
+"    <p>"
+"      <a 
href='https://github.com/libyui/libyui-rest-api/blob/master/README.md'>"
+"      The Generic REST API documentation</a>"
+"    </p>"
+"    <p>"
+"      <a href='" << documentation_url << "'>"
+"      The REST API v1 specification</a>"
+"    </p>"
 "    </body>"
 "</html>";
+        content_encoding = "text/html";
+    }
+    else
+    {
+        Json::Value info;
+        info["documentation_url"] = documentation_url;
+        YJsonSerializer::save(info, body);
+        content_encoding = "application/json";
+    }
 
-    boost::replace_all(help, "@port@", 
std::to_string(YHttpServer::port_num()));
-
-    body << help;
+    error_code = MHD_HTTP_OK;
 }
 
-std::string YHttpRootHandler::contentEncoding()
+// does the client accept an HTML response?
+bool accepts_html(struct MHD_Connection *connection)
 {
-    return "text/html";
-}
+    const char *accept = MHD_lookup_connection_value(connection, 
MHD_HEADER_KIND, "Accept");
+    yuiDebug() << "Accept header: " << accept << std::endl;
 
-int YHttpRootHandler::errorCode()
-{
-    return MHD_HTTP_OK;
+    if (!accept) return false;
+    return strstr(accept, "text/html");
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libyui-rest-api-0.3.0/src/YHttpRootHandler.h 
new/libyui-rest-api-0.4.1/src/YHttpRootHandler.h
--- old/libyui-rest-api-0.3.0/src/YHttpRootHandler.h    2019-12-10 
17:02:47.000000000 +0100
+++ new/libyui-rest-api-0.4.1/src/YHttpRootHandler.h    2020-06-08 
17:07:52.000000000 +0200
@@ -28,15 +28,13 @@
     virtual ~YHttpRootHandler() {}
 
 protected:
-
-    virtual void body(struct MHD_Connection* connection,
+    virtual void process_request(struct MHD_Connection* connection,
         const char* url, const char* method, const char* upload_data,
-        size_t* upload_data_size, std::ostream& body, bool *redraw);
-
-    virtual int errorCode();
-
-    virtual std::string contentEncoding();
+        size_t* upload_data_size, std::ostream& body, int& error_code,
+        std::string& content_encoding, bool *redraw);
 
+private:
+    static const std::string documentation_url;
 };
 
 #endif // YHttpRootHandler_h
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libyui-rest-api-0.3.0/src/YHttpServer.cc 
new/libyui-rest-api-0.4.1/src/YHttpServer.cc
--- old/libyui-rest-api-0.3.0/src/YHttpServer.cc        2019-12-10 
17:02:47.000000000 +0100
+++ new/libyui-rest-api-0.4.1/src/YHttpServer.cc        2020-06-08 
17:07:52.000000000 +0200
@@ -36,6 +36,7 @@
 #include "YHttpHandler.h"
 #include "YHttpDialogHandler.h"
 #include "YHttpRootHandler.h"
+#include "YHttpVersionHandler.h"
 #include "YHttpAppHandler.h"
 #include "YHttpWidgetsHandler.h"
 #include "YHttpWidgetsActionHandler.h"
@@ -250,11 +251,12 @@
 
 void YHttpServer::start()
 {
-    mount("/", "GET", new YHttpRootHandler());
+    mount("/", "GET", new YHttpRootHandler(), false);
     mount("/dialog", "GET", new YHttpDialogHandler());
     mount("/widgets", "GET", new YHttpWidgetsHandler());
     mount("/widgets", "POST", new YHttpWidgetsActionHandler());
     mount("/application", "GET", new YHttpAppHandler());
+    mount("/version", "GET", new YHttpVersionHandler(), false);
 
     bool remote = remote_access();
 
@@ -331,7 +333,11 @@
     return redraw;
 }
 
-void YHttpServer::mount(const std::string& path, const std::string &method, 
YHttpHandler *handler)
+void YHttpServer::mount(std::string path, const std::string &method, 
YHttpHandler *handler, bool has_api_version)
 {
+    if (has_api_version)
+    {
+        path = std::string("/").append(YUI_API_VERSION).append(path);
+    }
     _mounts.push_back(YHttpMount(path, method, handler));
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libyui-rest-api-0.3.0/src/YHttpServer.h 
new/libyui-rest-api-0.4.1/src/YHttpServer.h
--- old/libyui-rest-api-0.3.0/src/YHttpServer.h 2019-12-10 17:02:47.000000000 
+0100
+++ new/libyui-rest-api-0.4.1/src/YHttpServer.h 2020-06-08 17:07:52.000000000 
+0200
@@ -29,6 +29,8 @@
 #define YUI_AUTH_USER       "YUI_AUTH_USER"
 #define YUI_AUTH_PASSWD     "YUI_AUTH_PASSWD"
 
+#define YUI_API_VERSION     "v1"
+
 struct MHD_Daemon;
 
 class YHttpServer
@@ -71,7 +73,7 @@
      */
     YHttpServerSockets sockets();
 
-    void mount(const std::string& path, const std::string &method, 
YHttpHandler *handler);
+    void mount(std::string path, const std::string &method, YHttpHandler 
*handler, bool has_api_version = true);
 
     int handle(struct MHD_Connection* connection,
         const char* url, const char* method, const char* upload_data,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libyui-rest-api-0.3.0/src/YHttpVersionHandler.cc 
new/libyui-rest-api-0.4.1/src/YHttpVersionHandler.cc
--- old/libyui-rest-api-0.3.0/src/YHttpVersionHandler.cc        1970-01-01 
01:00:00.000000000 +0100
+++ new/libyui-rest-api-0.4.1/src/YHttpVersionHandler.cc        2020-06-08 
17:07:52.000000000 +0200
@@ -0,0 +1,36 @@
+/*
+  Copyright (C) 2017 SUSE LLC
+
+  This library is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as
+  published by the Free Software Foundation; either version 2.1 of the
+  License, or (at your option) version 3.0 of the License. This library
+  is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+  License for more details. You should have received a copy of the GNU
+  Lesser General Public License along with this library; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+  Floor, Boston, MA 02110-1301 USA
+*/
+
+#include "YHttpVersionHandler.h"
+#include "YJsonSerializer.h"
+
+#include "YHttpServer.h"
+#include <microhttpd.h>
+#include <string>
+#include <json/json.h>
+
+void YHttpVersionHandler::process_request(struct MHD_Connection* connection,
+    const char* url, const char* method, const char* upload_data,
+    size_t* upload_data_size, std::ostream& body, int& error_code,
+    std::string& content_encoding, bool *redraw)
+{
+    Json::Value info;
+    info["api_version"] = YUI_API_VERSION;
+    YJsonSerializer::save(info, body);
+
+    content_encoding = "application/json";
+    error_code = MHD_HTTP_OK;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libyui-rest-api-0.3.0/src/YHttpVersionHandler.h 
new/libyui-rest-api-0.4.1/src/YHttpVersionHandler.h
--- old/libyui-rest-api-0.3.0/src/YHttpVersionHandler.h 1970-01-01 
01:00:00.000000000 +0100
+++ new/libyui-rest-api-0.4.1/src/YHttpVersionHandler.h 2020-06-08 
17:07:52.000000000 +0200
@@ -0,0 +1,38 @@
+/*
+  Copyright (C) 2020 SUSE LLC
+
+  This library is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as
+  published by the Free Software Foundation; either version 2.1 of the
+  License, or (at your option) version 3.0 of the License. This library
+  is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+  License for more details. You should have received a copy of the GNU
+  Lesser General Public License along with this library; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+  Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef YHttpVersionHandler_h
+#define YHttpVersionHandler_h
+
+#include "YHttpHandler.h"
+
+class YHttpVersionHandler : public YHttpHandler
+{
+
+public:
+
+    YHttpVersionHandler() {}
+    virtual ~YHttpVersionHandler() {}
+
+protected:
+
+    virtual void process_request(struct MHD_Connection* connection,
+        const char* url, const char* method, const char* upload_data,
+        size_t* upload_data_size, std::ostream& body, int& error_code,
+        std::string& content_encoding, bool *redraw);
+};
+
+#endif // YHttpVersionHandler_h
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libyui-rest-api-0.3.0/src/YHttpWidgetsActionHandler.cc 
new/libyui-rest-api-0.4.1/src/YHttpWidgetsActionHandler.cc
--- old/libyui-rest-api-0.3.0/src/YHttpWidgetsActionHandler.cc  2019-12-10 
17:02:47.000000000 +0100
+++ new/libyui-rest-api-0.4.1/src/YHttpWidgetsActionHandler.cc  2020-06-08 
17:07:52.000000000 +0200
@@ -40,9 +40,10 @@
 
 #include "YHttpWidgetsActionHandler.h"
 
-void YHttpWidgetsActionHandler::body(struct MHD_Connection* connection,
+void YHttpWidgetsActionHandler::process_request(struct MHD_Connection* 
connection,
     const char* url, const char* method, const char* upload_data,
-    size_t* upload_data_size, std::ostream& body, bool *redraw)
+    size_t* upload_data_size, std::ostream& body, int& error_code,
+    std::string& content_encoding, bool *redraw)
 {
     if ( YDialog::topmostDialog(false) )
     {
@@ -64,36 +65,34 @@
         if ( widgets.empty() )
         {
             body << "{ \"error\" : \"Widget not found\" }" << std::endl;
-            _error_code = MHD_HTTP_NOT_FOUND;
+            error_code = MHD_HTTP_NOT_FOUND;
         }
         else if ( const char* action = MHD_lookup_connection_value(connection, 
MHD_GET_ARGUMENT_KIND, "action") )
         {
             if( widgets.size() != 1 )
             {
                 body << "{ \"error\" : \"Multiple widgets found to act on, try 
using multicriteria search (label+id+type)\" }" << std::endl;
-                _error_code = MHD_HTTP_NOT_FOUND;
+                error_code = MHD_HTTP_NOT_FOUND;
             }
-            _error_code = do_action(widgets[0], action, connection, body);
+            else
+                error_code = do_action(widgets[0], action, connection, body);
 
             // the action possibly changed something in the UI, signalize 
redraw needed
-            if ( redraw && _error_code == MHD_HTTP_OK )
+            if ( redraw && error_code == MHD_HTTP_OK )
                 *redraw = true;
         }
         else
         {
             body << "{ \"error\" : \"Missing action parameter\" }" << 
std::endl;
-            _error_code = MHD_HTTP_NOT_FOUND;
+            error_code = MHD_HTTP_NOT_FOUND;
         }
     }
     else {
         body << "{ \"error\" : \"No dialog is open\" }" << std::endl;
-        _error_code = MHD_HTTP_NOT_FOUND;
+        error_code = MHD_HTTP_NOT_FOUND;
     }
-}
 
-std::string YHttpWidgetsActionHandler::contentEncoding()
-{
-    return "application/json";
+    content_encoding = "application/json";
 }
 
 int YHttpWidgetsActionHandler::do_action(YWidget *widget, const std::string 
&action, struct MHD_Connection *connection, std::ostream& body) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libyui-rest-api-0.3.0/src/YHttpWidgetsActionHandler.h 
new/libyui-rest-api-0.4.1/src/YHttpWidgetsActionHandler.h
--- old/libyui-rest-api-0.3.0/src/YHttpWidgetsActionHandler.h   2019-12-10 
17:02:47.000000000 +0100
+++ new/libyui-rest-api-0.4.1/src/YHttpWidgetsActionHandler.h   2020-06-08 
17:07:52.000000000 +0200
@@ -40,17 +40,13 @@
 
 protected:
 
-    virtual void body(struct MHD_Connection* connection,
+    virtual void process_request(struct MHD_Connection* connection,
         const char* url, const char* method, const char* upload_data,
-        size_t* upload_data_size, std::ostream& body, bool *redraw);
-
-    virtual int errorCode() {return _error_code;}
-
-    virtual std::string contentEncoding();
+        size_t* upload_data_size, std::ostream& body, int& error_code,
+        std::string& content_encoding, bool *redraw);
 
 private:
 
-    int _error_code;
 
     // TODO: move this somewhere else...
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libyui-rest-api-0.3.0/src/YHttpWidgetsHandler.cc 
new/libyui-rest-api-0.4.1/src/YHttpWidgetsHandler.cc
--- old/libyui-rest-api-0.3.0/src/YHttpWidgetsHandler.cc        2019-12-10 
17:02:47.000000000 +0100
+++ new/libyui-rest-api-0.4.1/src/YHttpWidgetsHandler.cc        2020-06-08 
17:07:52.000000000 +0200
@@ -21,9 +21,10 @@
 
 #include <microhttpd.h>
 
-void YHttpWidgetsHandler::body(struct MHD_Connection* connection,
+void YHttpWidgetsHandler::process_request(struct MHD_Connection* connection,
     const char* url, const char* method, const char* upload_data,
-    size_t* upload_data_size, std::ostream& body, bool *redraw)
+    size_t* upload_data_size, std::ostream& body, int& error_code,
+    std::string& content_encoding, bool *redraw)
 {
     if (YDialog::topmostDialog(false))  {
         WidgetArray widgets;
@@ -41,22 +42,18 @@
 
         if (widgets.empty()) {
             body << "{ \"error\" : \"Widget not found\" }" << std::endl;
-            _error_code = MHD_HTTP_NOT_FOUND;
+            error_code = MHD_HTTP_NOT_FOUND;
         }
         else {
             // non recursive dump
             YJsonSerializer::serialize(widgets, body, false);
-            _error_code = MHD_HTTP_OK;
+            error_code = MHD_HTTP_OK;
         }
     }
     else {
         body << "{ \"error\" : \"No dialog is open\" }" << std::endl;
-        _error_code = MHD_HTTP_NOT_FOUND;
+        error_code = MHD_HTTP_NOT_FOUND;
     }
-}
 
-std::string YHttpWidgetsHandler::contentEncoding()
-{
-    return "application/json";
+    content_encoding = "application/json";
 }
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libyui-rest-api-0.3.0/src/YHttpWidgetsHandler.h 
new/libyui-rest-api-0.4.1/src/YHttpWidgetsHandler.h
--- old/libyui-rest-api-0.3.0/src/YHttpWidgetsHandler.h 2019-12-10 
17:02:47.000000000 +0100
+++ new/libyui-rest-api-0.4.1/src/YHttpWidgetsHandler.h 2020-06-08 
17:07:52.000000000 +0200
@@ -29,17 +29,10 @@
 
 protected:
 
-    virtual void body(struct MHD_Connection* connection,
+    virtual void process_request(struct MHD_Connection* connection,
         const char* url, const char* method, const char* upload_data,
-        size_t* upload_data_size, std::ostream& body, bool *redraw);
-
-    virtual int errorCode() {return _error_code;}
-
-    virtual std::string contentEncoding();
-
-private:
-
-    int _error_code;
+        size_t* upload_data_size, std::ostream& body, int& error_code,
+        std::string& content_encoding, bool *redraw);
 };
 
 #endif // YHttpWidgetsHandler_h


Reply via email to