My first function

From ISPWiki
Jump to: navigation, search

In this article you can learn the information on how to add new functions to the COREmanager interface. As an example we will write a module for displaying information on the last login to the system. The article My first event handler describes how to collect the information.

COREmanager provides two methods for displaying the information. You first need to describe metadata.

Metadata

Metadata is an XML document describing how the information should display in the web-interface. First you will need to specify the system access log. Create the file core_mod_lastlogin.xml (or edit the existing one if you have already created the event handler):

<?xml version="1.0" encoding="UTF-8"?>
<mgrdata>
  <lang name="ru">
    <messages name="desktop">
      <msg name="menu_lastlogin">Registrations log</msg>
    </messages>
    <messages name="lastlogin">
      <msg name="title">Registrations log</msg>
      <msg name="user">Username</msg>
      <msg name="date">Registration time</msg>
    </messages>
  </lang>
  <mainmenu level="30">
    <node name="stat">
      <node name="lastlogin"/>
    </node>
  </mainmenu>

  <metadata name="lastlogin" type="list">
    <toolbar/>
    <coldata>
      <col name="user" type="data" sort="alpha"/>
      <col name="date" type="data" sort="alpha"/>
    </coldata>
  </metadata>
</mgrdata>

External handler

To make the panel use the external handler, you need to add a number of tags into metadata. Then we will proceed with a custom handler.

Metadata

You need to describe which program should be executed for performing a function. Add the following tags into the file core_mod_lastlogin.xml:

<?xml version="1.0" encoding="UTF8"?>
<mgrdata>
  <handler name="lastlogin.list" type="cgi">
    <func name="lastlogin"/>
  </handler>
</mgrdata>

For more information about documents' XML that are used in COREmanager, please refer to the article: [[1]].

Handler

Now, calling the function lastlogin will call your handler addon/lastlogin.list.

Following is the example of the this handler on shell.

#!/bin/sh
WD=var/lastlogin

if [ "0$AUTH_LEVEL" -lt 30 -o ! -d $WD ]; then
  echo "<doc/>"
else
  cd $WD
  echo "<doc>"
  for i in *; do
    cat $i | sed -e "s/^/<elem><user>$i<\\/user><date>/;s/$/<\\/date><\\/elem>/"
  done
  echo "</doc>"
fi

Restart the panel and view the log.

C++ CORE API

This method allows for the best performance, however we do not recommend that you use it unless you have enough experience in programming. Besides, you won't be able to write a transferable code that will be compatible with all platforms. You should have a separate build for each of them. However, you won't have to add anything into xml and this solution consumes less system resources.

Examplelastlogin.cpp:

#include <api/action.h>
#include <mgr/mgrfile.h>
#include <fstream>
#include <sstream>
#include <api/module.h>

#define WD  "var/lastlogin"

namespace {
using namespace isp_api;

class LastLoginAction : public ListAction {
public:
    LastLoginAction() : ListAction("lastlogin", MinLevel(lvAdmin)) {}
    virtual void List(Session &ses) const {
        if (!mgr_file::Exists(WD))
            return;
        mgr_file::Dir dir(WD);
        while (dir.Read()) {
            std::ifstream in(dir.FullName());
            while (in.good()) {
                std::stringbuf buf; 
                in.get(buf);
                in.get();
                if (!buf.str().empty()) {
                    ses.NewElem();
                    ses.AddChildTag("user", dir.name());
                    ses.AddChildTag("data", buf.str());
                }
            }
        }
    }
};

MODULE_INIT(lastloginaction, "") {
    new LastLoginAction();
}
} // end of private namespace

Upload and configure the library. For more information, please refer to the articles Building custom components and Upload custom libraries.