Source

quechua / src / python-interface.cc

Full commit
/* 
 * Quechua - the lightweight data mining framework
 *
 * Copyright (C) 2012 Marek Denis <quechua@octogan.net>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "../include/python-interface.h"

int Python::initialized = 0;

void Python::init() {


    PyObject *pPath, *pSys_path;
    
    if(!Py_IsInitialized()) {
        Py_Initialize();
        initialized = 1;

        pSys_path = PySys_GetObject("path");
        if (pSys_path == NULL)
            return;
        pPath = PyString_FromString("/opt/quechua/sbin");
        if (pPath == NULL) {
            LOG(ERROR) << "pPath";
            return;
        }
        if (PyList_Append(pSys_path, pPath) < 0) {
            LOG(ERROR) << "PyList_Append";
            return;
        }
// TODO(marek): causes segmentation fault, no idea why. possible memleak
//        Py_XDECREF(pSys_path); 
        Py_XDECREF(pPath);
    }
}

int Python::convert_to_seconds(const string_t& time) {

    init();

    int seconds = 3600*24; // 1D
    string_t log;

    PyObject *pName, *pModule, *pArgs, *pFunc, *pValue;
    PyObject *pItem, *pLog;


    pName   = PyString_FromString("time_converter");
    
    pModule = PyImport_Import(pName);
    Py_DECREF(pName);
    if(pModule!=NULL) { 
        pFunc = PyObject_GetAttrString(pModule, "convert_to_seconds");
        if(pFunc && PyCallable_Check(pFunc)) {
            pArgs = PyTuple_New(1);
            pValue = PyString_FromString(time.c_str());
            PyTuple_SetItem(pArgs,0,pValue);

            pValue = PyObject_CallObject(pFunc,pArgs);
            if(pValue!=NULL) {

                pItem = PyTuple_GetItem(pValue, 0);
                seconds = PyInt_AsLong(pItem);
                
                pItem = PyTuple_GetItem(pValue,1);
                log   = PyString_AsString(pItem);
                if (log.compare(""))
                    LOG(WARN) << log;
                Py_XDECREF(pValue);
                Py_XDECREF(pItem);

            }
            else {
                LOG(WARN) << "Python script returned null value, setting default value (1D)";
                PyErr_Print();
            }
        
            Py_XDECREF(pFunc);
            Py_XDECREF(pArgs);
        }
        Py_XDECREF(pModule);
    }
    else 
        PyErr_Print();
    
    return seconds;
};

void Python::calculate_ranges_from_interval(const string_t& time,string_t& from, string_t& to) {

    init();
    PyObject *pName, *pModule, *pArgs, *pFunc, *pValue;
    PyObject *pItem, *pLog;

    pName = PyString_FromString("time_converter");
    
    pModule = PyImport_Import(pName);
    Py_DECREF(pName);
    if(pModule!=NULL) { 
        pFunc = PyObject_GetAttrString(pModule, "calculate_ranges_from_interval");
        if(pFunc && PyCallable_Check(pFunc)) {
            pArgs = PyTuple_New(1);
            pValue = PyString_FromString(time.c_str());
            PyTuple_SetItem(pArgs,0,pValue);

            pValue = PyObject_CallObject(pFunc,pArgs);
            if(pValue!=NULL) {

                pItem = PyTuple_GetItem(pValue,0);
                from = PyString_AsString(pItem);

                Py_XDECREF(pItem);
                
                pItem = PyTuple_GetItem(pValue,1);
                to   = PyString_AsString(pItem);

                Py_XDECREF(pValue);
                Py_XDECREF(pItem);

            }
            else {
                LOG(WARN) << "Python script returned null value, setting default value (1H)";
                PyErr_Print();
            }
        
            Py_XDECREF(pFunc);
            Py_XDECREF(pArgs);
        }
        Py_XDECREF(pModule);
    }
    else 
        PyErr_Print();

};
/**
 * Input is read from the channel section in the configuration.
 * 
 **/ 
void Python::format_dates_from_input(const string_t& input_from, const string_t& input_to,
                                     string_t& output_from, string_t& output_to) {

    init();
    PyObject *pName, *pModule, *pArgs, *pFunc, *pValue;
    PyObject *pItem, *pLog;

    pName = PyString_FromString("time_converter");
    
    pModule = PyImport_Import(pName);
    Py_DECREF(pName);
    if(pModule!=NULL) { 
        pFunc = PyObject_GetAttrString(pModule, "format_dates_from_input");
        if(pFunc && PyCallable_Check(pFunc)) {
            pArgs = PyTuple_New(2);
            pValue = PyString_FromString(input_from.c_str());
            PyTuple_SetItem(pArgs,0,pValue);

            pValue = PyString_FromString(input_to.c_str());
            PyTuple_SetItem(pArgs,1,pValue);

            pValue = PyObject_CallObject(pFunc,pArgs);
            if(pValue!=NULL) {

                pItem = PyTuple_GetItem(pValue,0);
                output_from = PyString_AsString(pItem);

                Py_XDECREF(pItem);
                
                pItem = PyTuple_GetItem(pValue,1);
                output_to   = PyString_AsString(pItem);

                Py_XDECREF(pValue);
                Py_XDECREF(pItem);

            }
            else {
                LOG(WARN) << "Python script returned null value, setting default value (1H)";
                PyErr_Print();
            }
        
            Py_XDECREF(pFunc);
            Py_XDECREF(pArgs);
        }
        Py_XDECREF(pModule);
    }
    else 
        PyErr_Print();

};

void Python::sqlize_date_string(const string_t& input_date, string_t& sqlized_date) {
    init();
    sqlized_date = "CURRENT_TIMESTAMP";
    PyObject *pName, *pModule, *pArgs, *pFunc, *pValue;
    PyObject *pItem, *pLog;

    pName = PyString_FromString("time_converter");
    
    pModule = PyImport_Import(pName);
    Py_DECREF(pName);
    if(pModule!=NULL) {
        pFunc = PyObject_GetAttrString(pModule,"sqlize_date_string");
        if(pFunc && PyCallable_Check(pFunc)) {
            pArgs = PyTuple_New(1);
            pValue = PyString_FromString(input_date.c_str());
            PyTuple_SetItem(pArgs,0,pValue);

            pValue = PyObject_CallObject(pFunc,pArgs);
            if(pValue!=NULL) {
                sqlized_date = PyString_AsString(pValue);
                Py_XDECREF(pValue);

            }
            else {
                LOG(WARN) << "Python script returned null value, setting default value CURRENT_TIMESTAMP";
                PyErr_Print();
            }
        
            Py_XDECREF(pFunc);
            Py_XDECREF(pArgs);
        }
        Py_XDECREF(pModule);
    }
    else {
        PyErr_Print();
        LOG(WARN) << "Cannot load Python module time_converter."; 
    }
};