<commit_before>/****************************************************************************
 *   Copyright (C) 2017-2018 Savoir-faire Linux                                  *
 *   Author: Nicolas Jäger <nicolas.jager@savoirfairelinux.com>             *
 *   Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>           *
 *                                                                          *
 *   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) any later version.     *
 *                                                                          *
 *   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 General Public License      *
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
 ***************************************************************************/
#include "callbackshandler.h"

// Models and database
#include "api/account.h"
#include "api/lrc.h"
#include "api/newaccountmodel.h"
#include "api/datatransfermodel.h"

// Lrc
#include "account.h"
#include "dbus/callmanager.h"
#include "dbus/configurationmanager.h"
#include "dbus/presencemanager.h"
#include "namedirectory.h"

// DRing
#include <datatransfer_interface.h>

namespace lrc
{

using namespace api;

CallbacksHandler::CallbacksHandler(const Lrc& parent)
: QObject()
, parent(parent)
{
    // Get signals from daemon
    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::incomingAccountMessage,
            this,
            &CallbacksHandler::slotNewAccountMessage);

    connect(&PresenceManager::instance(),
            &PresenceManagerInterface::newBuddyNotification,
            this,
            &CallbacksHandler::slotNewBuddySubscription);

    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::contactAdded,
            this,
            &CallbacksHandler::slotContactAdded);

    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::contactRemoved,
            this,
            &CallbacksHandler::slotContactRemoved);

    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::incomingTrustRequest,
            this,
            &CallbacksHandler::slotIncomingContactRequest);

    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::accountMessageStatusChanged,
            this,
            &CallbacksHandler::slotAccountMessageStatusChanged);

    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::accountDetailsChanged,
            this,
            &CallbacksHandler::slotAccountDetailsChanged);

    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::registrationStateChanged,
            this,
            &CallbacksHandler::slotRegistrationStateChanged);

    connect(&CallManager::instance(),
            &CallManagerInterface::incomingCall,
            this,
            &CallbacksHandler::slotIncomingCall);

    connect(&CallManager::instance(),
            &CallManagerInterface::callStateChanged,
            this,
            &CallbacksHandler::slotCallStateChanged);

    connect(&CallManager::instance(),
            &CallManagerInterface::conferenceCreated,
            this,
            &CallbacksHandler::slotConferenceCreated);

    connect(&CallManager::instance(),
            &CallManagerInterface::conferenceRemoved,
            this,
            &CallbacksHandler::slotConferenceRemoved);

    connect(&CallManager::instance(),
            &CallManagerInterface::conferenceChanged,
            this,
            &CallbacksHandler::slotConferenceChanged);

    connect(&CallManager::instance(),
            &CallManagerInterface::incomingMessage,
            this,
            &CallbacksHandler::slotIncomingMessage);

    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::dataTransferEvent,
            this,
            &CallbacksHandler::slotDataTransferEvent);

    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::knownDevicesChanged,
            this,
            &CallbacksHandler::slotKnownDevicesChanged);

    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::deviceRevocationEnded,
            this,
            &CallbacksHandler::slotDeviceRevokationEnded);

    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::exportOnRingEnded,
            this,
            &CallbacksHandler::slotExportOnRingEnded);

    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::nameRegistrationEnded,
            this,
            &CallbacksHandler::slotNameRegistrationEnded);

    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::registeredNameFound,
            this,
            &CallbacksHandler::slotRegisteredNameFound);

    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::migrationEnded,
            this,
            &CallbacksHandler::slotMigrationEnded);
}

CallbacksHandler::~CallbacksHandler()
{

}

void
CallbacksHandler::slotNewAccountMessage(const QString& accountId,
                                        const QString& from,
                                        const QMap<QString,QString>& payloads)
{
    std::map<std::string,std::string> stdPayloads;

    for (auto item : payloads.keys()) {
        stdPayloads[item.toStdString()] = payloads.value(item).toStdString();
    }

    auto accountId2 = accountId.toStdString();
    auto from2 = from.toStdString();

    emit newAccountMessage(accountId2, from2, stdPayloads);
}

void
CallbacksHandler::slotNewBuddySubscription(const QString& accountId,
                                           const QString& uri,
                                           bool status,
                                           const QString& message)
{
    Q_UNUSED(accountId)
    Q_UNUSED(status)
    Q_UNUSED(message)
    emit newBuddySubscription(uri.toStdString(), status);
}

void
CallbacksHandler::slotContactAdded(const QString& accountId,
                                   const QString& contactUri,
                                   bool confirmed)
{
    emit contactAdded(accountId.toStdString(), contactUri.toStdString(), confirmed);
}

void
CallbacksHandler::slotContactRemoved(const QString& accountId,
                                     const QString& contactUri,
                                     bool banned)
{
    emit contactRemoved(accountId.toStdString(), contactUri.toStdString(), banned);
}

void
CallbacksHandler::slotIncomingContactRequest(const QString& accountId,
                                             const QString& ringId,
                                             const QByteArray& payload,
                                             time_t time)
{
    Q_UNUSED(time)
    emit incomingContactRequest(accountId.toStdString(), ringId.toStdString(), payload.toStdString());
}

void
CallbacksHandler::slotIncomingCall(const QString &accountId, const QString &callId, const QString &fromUri)
{
    if (fromUri.contains("ring.dht")) {
        auto fromQString = fromUri.right(50);
        fromQString = fromQString.left(40);
        emit incomingCall(accountId.toStdString(), callId.toStdString(), fromQString.toStdString());
    } else {
        auto left = fromUri.indexOf("<")+1;
        auto right = fromUri.indexOf("@");
        auto fromQString = fromUri.mid(left, right-left);

        emit incomingCall(accountId.toStdString(), callId.toStdString(), fromQString.toStdString());
    }
}

void
CallbacksHandler::slotCallStateChanged(const QString& callId, const QString& state, int code)
{
    emit callStateChanged(callId.toStdString(), state.toStdString(), code);
}

void
CallbacksHandler::slotAccountDetailsChanged(const QString& accountId,
                                            const MapStringString& details)
{
    emit accountDetailsChanged(accountId.toStdString(), convertMap(details));
}

void
CallbacksHandler::slotRegistrationStateChanged(const QString& accountId,
                                               const QString& registration_state,
                                               unsigned detail_code,
                                               const QString& detail_str)
{
    (void) detail_code;
    (void) detail_str;
    emit accountStatusChanged(accountId.toStdString(), lrc::api::account::to_status(registration_state.toStdString()));
}

void
CallbacksHandler::slotIncomingMessage(const QString& callId,
                                      const QString& from,
                                      const QMap<QString,QString>& interaction)
{
    std::string from2;
    if (from.contains("ring.dht")) {
        from2 = from.left(40).toStdString();
    }
    else {
        auto left = from.indexOf(":")+1;
        auto right = from.indexOf("@");
        from2 = from.mid(left, right-left).toStdString();
    }

    for (auto& e : interaction.toStdMap()) {
        if (e.first.contains("x-ring/ring.profile.vcard")) {
            auto pieces0 = e.first.split( ";" );
            auto pieces1 = pieces0[1].split( "," );
            auto pieces2 = pieces1[1].split( "=" );
            auto pieces3 = pieces1[2].split( "=" );
            emit incomingVCardChunk(callId.toStdString(),
                                    from2,
                                    pieces2[1].toInt(),
                                    pieces3[1].toInt(),
                                    e.second.toStdString());
        } else { // we consider it as an usual message interaction
            emit incomingCallMessage(callId.toStdString(), from2, e.second.toStdString());
        }
    }
}

void
CallbacksHandler::slotConferenceCreated(const QString& callId)
{
    emit conferenceCreated(callId.toStdString());
}

void
CallbacksHandler::slotConferenceChanged(const QString& callId, const QString& state)
{
    slotCallStateChanged(callId, state, 0);
}

void
CallbacksHandler::slotConferenceRemoved(const QString& callId)
{
    emit conferenceRemoved(callId.toStdString());
}

void
CallbacksHandler::slotAccountMessageStatusChanged(const QString& accountId,
                                                  const uint64_t id,
                                                  const QString& to, int status)
{
    emit accountMessageStatusChanged(accountId.toStdString(), id,
                                     to.toStdString(), status);
}

void
CallbacksHandler::slotDataTransferEvent(qulonglong dringId, uint codeStatus)
{
    auto event = DRing::DataTransferEventCode(codeStatus);

    api::datatransfer::Info info;
    parent.getDataTransferModel().transferInfo(dringId, info);

    // WARNING: info.status could be INVALID in case of async signaling
    // So listeners must only take account of dringId in such case.
    // Is useful for "termination" status like unjoinable_peer.

    switch (event) {
    case DRing::DataTransferEventCode::created:
        emit transferStatusCreated(static_cast<long long>(dringId), info);
        break;
    case DRing::DataTransferEventCode::closed_by_host:
    case DRing::DataTransferEventCode::closed_by_peer:
        emit transferStatusCanceled(static_cast<long long>(dringId), info);
        break;
    case DRing::DataTransferEventCode::wait_peer_acceptance:
        emit transferStatusAwaitingPeer(static_cast<long long>(dringId), info);
        break;
    case DRing::DataTransferEventCode::wait_host_acceptance:
        emit transferStatusAwaitingHost(static_cast<long long>(dringId), info);
        break;
    case DRing::DataTransferEventCode::ongoing:
        emit transferStatusOngoing(static_cast<long long>(dringId), info);
        break;
    case DRing::DataTransferEventCode::finished:
        emit transferStatusFinished(static_cast<long long>(dringId), info);
        break;
    case DRing::DataTransferEventCode::invalid_pathname:
    case DRing::DataTransferEventCode::unsupported:
        emit transferStatusError(static_cast<long long>(dringId), info);
        break;
    case DRing::DataTransferEventCode::timeout_expired:
        emit transferStatusTimeoutExpired(static_cast<long long>(dringId), info);
        break;
    case DRing::DataTransferEventCode::unjoinable_peer:
        emit transferStatusUnjoinable(static_cast<long long>(dringId), info);
        break;
    }
}

void
CallbacksHandler::slotKnownDevicesChanged(const QString& accountId,
                                          const QMap<QString, QString>& devices)
{
    std::map<std::string, std::string> stdDevices;
    for (auto item : devices.keys())
        stdDevices[item.toStdString()] = devices.value(item).toStdString();
    auto accountId2 = accountId.toStdString();
    emit knownDevicesChanged(accountId2, stdDevices);
}

void
CallbacksHandler::slotDeviceRevokationEnded(const QString& accountId,
                                            const QString& deviceId,
                                            const int status)
{
    emit deviceRevocationEnded(accountId.toStdString(), deviceId.toStdString(), status);
}

void
CallbacksHandler::slotExportOnRingEnded(const QString& accountId, int status, const QString& pin)
{
    emit exportOnRingEnded(accountId.toStdString(), status, pin.toStdString());
}

void
CallbacksHandler::slotNameRegistrationEnded(const QString& accountId, int status, const QString& name)
{
    emit nameRegistrationEnded(accountId.toStdString(), status, name.toStdString());
}

void
CallbacksHandler::slotRegisteredNameFound(const QString& accountId, int status, const QString& address, const QString& name)
{
    emit registeredNameFound(accountId.toStdString(), status, address.toStdString(), name.toStdString());
}

void
CallbacksHandler::slotMigrationEnded(const QString& accountId, const QString& status)
{
    emit migrationEnded(accountId.toStdString(), status == "SUCCESS");
}

} // namespace lrc
<commit_msg>signals: force connections as queued<commit_after>/****************************************************************************
 *   Copyright (C) 2017-2018 Savoir-faire Linux                                  *
 *   Author: Nicolas Jäger <nicolas.jager@savoirfairelinux.com>             *
 *   Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>           *
 *                                                                          *
 *   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) any later version.     *
 *                                                                          *
 *   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 General Public License      *
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
 ***************************************************************************/
#include "callbackshandler.h"

// Models and database
#include "api/account.h"
#include "api/lrc.h"
#include "api/newaccountmodel.h"
#include "api/datatransfermodel.h"

// Lrc
#include "account.h"
#include "dbus/callmanager.h"
#include "dbus/configurationmanager.h"
#include "dbus/presencemanager.h"
#include "namedirectory.h"

// DRing
#include <datatransfer_interface.h>

namespace lrc
{

using namespace api;

CallbacksHandler::CallbacksHandler(const Lrc& parent)
: QObject()
, parent(parent)
{
    // Get signals from daemon
    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::incomingAccountMessage,
            this,
            &CallbacksHandler::slotNewAccountMessage,
            Qt::QueuedConnection);

    connect(&PresenceManager::instance(),
            &PresenceManagerInterface::newBuddyNotification,
            this,
            &CallbacksHandler::slotNewBuddySubscription,
            Qt::QueuedConnection);

    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::contactAdded,
            this,
            &CallbacksHandler::slotContactAdded,
            Qt::QueuedConnection);

    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::contactRemoved,
            this,
            &CallbacksHandler::slotContactRemoved,
            Qt::QueuedConnection);

    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::incomingTrustRequest,
            this,
            &CallbacksHandler::slotIncomingContactRequest,
            Qt::QueuedConnection);

    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::accountMessageStatusChanged,
            this,
            &CallbacksHandler::slotAccountMessageStatusChanged,
            Qt::QueuedConnection);

    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::accountDetailsChanged,
            this,
            &CallbacksHandler::slotAccountDetailsChanged,
            Qt::QueuedConnection);

    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::registrationStateChanged,
            this,
            &CallbacksHandler::slotRegistrationStateChanged,
            Qt::QueuedConnection);

    connect(&CallManager::instance(),
            &CallManagerInterface::incomingCall,
            this,
            &CallbacksHandler::slotIncomingCall,
            Qt::QueuedConnection);

    connect(&CallManager::instance(),
            &CallManagerInterface::callStateChanged,
            this,
            &CallbacksHandler::slotCallStateChanged,
            Qt::QueuedConnection);

    connect(&CallManager::instance(),
            &CallManagerInterface::conferenceCreated,
            this,
            &CallbacksHandler::slotConferenceCreated,
            Qt::QueuedConnection);

    connect(&CallManager::instance(),
            &CallManagerInterface::conferenceRemoved,
            this,
            &CallbacksHandler::slotConferenceRemoved,
            Qt::QueuedConnection);

    connect(&CallManager::instance(),
            &CallManagerInterface::conferenceChanged,
            this,
            &CallbacksHandler::slotConferenceChanged,
            Qt::QueuedConnection);

    connect(&CallManager::instance(),
            &CallManagerInterface::incomingMessage,
            this,
            &CallbacksHandler::slotIncomingMessage,
            Qt::QueuedConnection);

    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::dataTransferEvent,
            this,
            &CallbacksHandler::slotDataTransferEvent,
            Qt::QueuedConnection);

    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::knownDevicesChanged,
            this,
            &CallbacksHandler::slotKnownDevicesChanged,
            Qt::QueuedConnection);

    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::deviceRevocationEnded,
            this,
            &CallbacksHandler::slotDeviceRevokationEnded,
            Qt::QueuedConnection);

    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::exportOnRingEnded,
            this,
            &CallbacksHandler::slotExportOnRingEnded,
            Qt::QueuedConnection);

    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::nameRegistrationEnded,
            this,
            &CallbacksHandler::slotNameRegistrationEnded,
            Qt::QueuedConnection);

    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::registeredNameFound,
            this,
            &CallbacksHandler::slotRegisteredNameFound,
            Qt::QueuedConnection);

    connect(&ConfigurationManager::instance(),
            &ConfigurationManagerInterface::migrationEnded,
            this,
            &CallbacksHandler::slotMigrationEnded,
            Qt::QueuedConnection);
}

CallbacksHandler::~CallbacksHandler()
{

}

void
CallbacksHandler::slotNewAccountMessage(const QString& accountId,
                                        const QString& from,
                                        const QMap<QString,QString>& payloads)
{
    std::map<std::string,std::string> stdPayloads;

    for (auto item : payloads.keys()) {
        stdPayloads[item.toStdString()] = payloads.value(item).toStdString();
    }

    auto accountId2 = accountId.toStdString();
    auto from2 = from.toStdString();

    emit newAccountMessage(accountId2, from2, stdPayloads);
}

void
CallbacksHandler::slotNewBuddySubscription(const QString& accountId,
                                           const QString& uri,
                                           bool status,
                                           const QString& message)
{
    Q_UNUSED(accountId)
    Q_UNUSED(status)
    Q_UNUSED(message)
    emit newBuddySubscription(uri.toStdString(), status);
}

void
CallbacksHandler::slotContactAdded(const QString& accountId,
                                   const QString& contactUri,
                                   bool confirmed)
{
    emit contactAdded(accountId.toStdString(), contactUri.toStdString(), confirmed);
}

void
CallbacksHandler::slotContactRemoved(const QString& accountId,
                                     const QString& contactUri,
                                     bool banned)
{
    emit contactRemoved(accountId.toStdString(), contactUri.toStdString(), banned);
}

void
CallbacksHandler::slotIncomingContactRequest(const QString& accountId,
                                             const QString& ringId,
                                             const QByteArray& payload,
                                             time_t time)
{
    Q_UNUSED(time)
    emit incomingContactRequest(accountId.toStdString(), ringId.toStdString(), payload.toStdString());
}

void
CallbacksHandler::slotIncomingCall(const QString &accountId, const QString &callId, const QString &fromUri)
{
    if (fromUri.contains("ring.dht")) {
        auto fromQString = fromUri.right(50);
        fromQString = fromQString.left(40);
        emit incomingCall(accountId.toStdString(), callId.toStdString(), fromQString.toStdString());
    } else {
        auto left = fromUri.indexOf("<")+1;
        auto right = fromUri.indexOf("@");
        auto fromQString = fromUri.mid(left, right-left);

        emit incomingCall(accountId.toStdString(), callId.toStdString(), fromQString.toStdString());
    }
}

void
CallbacksHandler::slotCallStateChanged(const QString& callId, const QString& state, int code)
{
    emit callStateChanged(callId.toStdString(), state.toStdString(), code);
}

void
CallbacksHandler::slotAccountDetailsChanged(const QString& accountId,
                                            const MapStringString& details)
{
    emit accountDetailsChanged(accountId.toStdString(), convertMap(details));
}

void
CallbacksHandler::slotRegistrationStateChanged(const QString& accountId,
                                               const QString& registration_state,
                                               unsigned detail_code,
                                               const QString& detail_str)
{
    (void) detail_code;
    (void) detail_str;
    emit accountStatusChanged(accountId.toStdString(), lrc::api::account::to_status(registration_state.toStdString()));
}

void
CallbacksHandler::slotIncomingMessage(const QString& callId,
                                      const QString& from,
                                      const QMap<QString,QString>& interaction)
{
    std::string from2;
    if (from.contains("ring.dht")) {
        from2 = from.left(40).toStdString();
    }
    else {
        auto left = from.indexOf(":")+1;
        auto right = from.indexOf("@");
        from2 = from.mid(left, right-left).toStdString();
    }

    for (auto& e : interaction.toStdMap()) {
        if (e.first.contains("x-ring/ring.profile.vcard")) {
            auto pieces0 = e.first.split( ";" );
            auto pieces1 = pieces0[1].split( "," );
            auto pieces2 = pieces1[1].split( "=" );
            auto pieces3 = pieces1[2].split( "=" );
            emit incomingVCardChunk(callId.toStdString(),
                                    from2,
                                    pieces2[1].toInt(),
                                    pieces3[1].toInt(),
                                    e.second.toStdString());
        } else { // we consider it as an usual message interaction
            emit incomingCallMessage(callId.toStdString(), from2, e.second.toStdString());
        }
    }
}

void
CallbacksHandler::slotConferenceCreated(const QString& callId)
{
    emit conferenceCreated(callId.toStdString());
}

void
CallbacksHandler::slotConferenceChanged(const QString& callId, const QString& state)
{
    slotCallStateChanged(callId, state, 0);
}

void
CallbacksHandler::slotConferenceRemoved(const QString& callId)
{
    emit conferenceRemoved(callId.toStdString());
}

void
CallbacksHandler::slotAccountMessageStatusChanged(const QString& accountId,
                                                  const uint64_t id,
                                                  const QString& to, int status)
{
    emit accountMessageStatusChanged(accountId.toStdString(), id,
                                     to.toStdString(), status);
}

void
CallbacksHandler::slotDataTransferEvent(qulonglong dringId, uint codeStatus)
{
    auto event = DRing::DataTransferEventCode(codeStatus);

    api::datatransfer::Info info;
    parent.getDataTransferModel().transferInfo(dringId, info);

    // WARNING: info.status could be INVALID in case of async signaling
    // So listeners must only take account of dringId in such case.
    // Is useful for "termination" status like unjoinable_peer.

    switch (event) {
    case DRing::DataTransferEventCode::created:
        emit transferStatusCreated(static_cast<long long>(dringId), info);
        break;
    case DRing::DataTransferEventCode::closed_by_host:
    case DRing::DataTransferEventCode::closed_by_peer:
        emit transferStatusCanceled(static_cast<long long>(dringId), info);
        break;
    case DRing::DataTransferEventCode::wait_peer_acceptance:
        emit transferStatusAwaitingPeer(static_cast<long long>(dringId), info);
        break;
    case DRing::DataTransferEventCode::wait_host_acceptance:
        emit transferStatusAwaitingHost(static_cast<long long>(dringId), info);
        break;
    case DRing::DataTransferEventCode::ongoing:
        emit transferStatusOngoing(static_cast<long long>(dringId), info);
        break;
    case DRing::DataTransferEventCode::finished:
        emit transferStatusFinished(static_cast<long long>(dringId), info);
        break;
    case DRing::DataTransferEventCode::invalid_pathname:
    case DRing::DataTransferEventCode::unsupported:
        emit transferStatusError(static_cast<long long>(dringId), info);
        break;
    case DRing::DataTransferEventCode::timeout_expired:
        emit transferStatusTimeoutExpired(static_cast<long long>(dringId), info);
        break;
    case DRing::DataTransferEventCode::unjoinable_peer:
        emit transferStatusUnjoinable(static_cast<long long>(dringId), info);
        break;
    }
}

void
CallbacksHandler::slotKnownDevicesChanged(const QString& accountId,
                                          const QMap<QString, QString>& devices)
{
    std::map<std::string, std::string> stdDevices;
    for (auto item : devices.keys())
        stdDevices[item.toStdString()] = devices.value(item).toStdString();
    auto accountId2 = accountId.toStdString();
    emit knownDevicesChanged(accountId2, stdDevices);
}

void
CallbacksHandler::slotDeviceRevokationEnded(const QString& accountId,
                                            const QString& deviceId,
                                            const int status)
{
    emit deviceRevocationEnded(accountId.toStdString(), deviceId.toStdString(), status);
}

void
CallbacksHandler::slotExportOnRingEnded(const QString& accountId, int status, const QString& pin)
{
    emit exportOnRingEnded(accountId.toStdString(), status, pin.toStdString());
}

void
CallbacksHandler::slotNameRegistrationEnded(const QString& accountId, int status, const QString& name)
{
    emit nameRegistrationEnded(accountId.toStdString(), status, name.toStdString());
}

void
CallbacksHandler::slotRegisteredNameFound(const QString& accountId, int status, const QString& address, const QString& name)
{
    emit registeredNameFound(accountId.toStdString(), status, address.toStdString(), name.toStdString());
}

void
CallbacksHandler::slotMigrationEnded(const QString& accountId, const QString& status)
{
    emit migrationEnded(accountId.toStdString(), status == "SUCCESS");
}

} // namespace lrc
<|endoftext|>


<commit_before>//system stuff
#include <string>
//ros stuff
#include "ros/ros.h"
#include "sensor_msgs/Joy.h"
#include "sensor_msgs/JointState.h"
#include "capybarauno/capybara_ticks.h"
#include "tf/transform_broadcaster.h"
#include "nav_msgs/Odometry.h"
//own stuff
#include "malComm/mal_comm.h"
#include "malComm/mal_primitives.h"

using namespace std;

int serialFd;
int beatcnt=0;
int beatingheart=0;
struct Packet_Decoder packet_decoder;
struct Packet packet;
struct Speed_Payload speedPayload;
struct State_Payload statePayload;
struct Packet heartbeat_packet;
struct Heartbeat_Payload heartbeat;

ros::Publisher ticks_publisher;
ros::Publisher joint_ticks_publisher;
ros::Publisher odom_pub;

capybarauno::capybara_ticks currentTicks;
capybarauno::capybara_ticks previousTicks;

unsigned int _oldLeft=0;
unsigned int _oldRight=0;

struct configuration{
    string serial_device;
    string published_ticks_topic;
    string published_joint_ticks_topic;
    string cmdvel_topic;
    string subscribed_ticks_topic;
    double kbaseline;
    double kleft;
    double kright;
    string published_odometry_topic;
    string published_link_name;
    string published_odom_link_name;
    int ascii;
    int debug;
    int heartbeat;

};

struct configuration c;
double x,y,t=0;
uint32_t tick_sequence=0;
int firstMessage=1;

void cmdvelCallback(const geometry_msgs::Twist::ConstPtr& twist)
{
    if(!ros::ok()) return;
    //get absolute speed values, expressed in tick per interval
    double translational_velocity = twist->linear.x;
    double rotational_velocity    = -twist->angular.z/(c.kbaseline*2);
    capybarauno::capybara_ticks ct;
    ct.leftEncoder=(uint16_t)((-translational_velocity+rotational_velocity)/(c.kleft*1000));
    ct.rightEncoder=(uint16_t)((translational_velocity+rotational_velocity)/(c.kright*1000));
    //ROS_INFO("CMDVEL %f %f %d %d",twist->linear.x,twist->angular.z,ct.leftEncoder,ct.rightEncoder);
    speedPayload.leftTick=ct.leftEncoder;
    speedPayload.rightTick=ct.rightEncoder;
    packet.speed=speedPayload;
    char buf[255];
    char* pEnd=Packet_write(&packet,buf,c.ascii);
    sendToUart(serialFd,buf,pEnd-buf,0);

}

Packet read_ticks_from_uart(int serialDevice, Packet_Decoder& decoder){
    char chunk;
    int complete=0;
    Packet read_packet;
    while(read(serialDevice, &chunk, 1)>0 && !complete){
        complete = Packet_Decoder_putChar(&decoder,(unsigned char)chunk);
    }
    if(complete){
        Packet_parse(decoder.buffer_start,&read_packet,c.ascii);
    }
    return read_packet;
}

void RobotCommunication_init(){
    initConsts();
    Packet_Decoder_init(&packet_decoder,c.ascii);
    packet.id=Speed_Payload_ID;
    serialFd=openPort((char*)c.serial_device.c_str());
    if(c.debug){
        printf("serial port status: %d\n",serialFd);
        fflush(stdout);
    }
}

void send_heartbeat(int &cnt){
    if(cnt%2==0){
        heartbeat_packet.seq++;
        char heartbuff[255];
        char* pEnd=Packet_write(&heartbeat_packet,heartbuff,c.ascii);
        sendToUart(serialFd,heartbuff,pEnd-heartbuff,0);
//        if(c.debug){
//            printf("SENDING: %s\n",heartbuff);
//            fflush(stdout);
//        }

    }
    cnt++;
}

void sendOdometry(tf::TransformBroadcaster& odom_broadcaster, capybarauno::capybara_ticks ticks){
    uint16_t ult;
    uint16_t urt;
    if(firstMessage){
        previousTicks.leftEncoder=ticks.leftEncoder;
        previousTicks.rightEncoder=ticks.rightEncoder;
        firstMessage=0;
    }
    else{
    ult = ticks.leftEncoder-previousTicks.leftEncoder;
    urt = ticks.rightEncoder-previousTicks.rightEncoder;
    previousTicks.leftEncoder=ticks.leftEncoder;
    previousTicks.rightEncoder=ticks.rightEncoder;
    int16_t lt = (int16_t)ult;
    int16_t rt = (int16_t)urt;

    double left=-(double)lt*c.kleft;
    double right=(double)rt*c.kright;
    double s = (left+right)/2;
    t-=(right-left)/c.kbaseline;
    x+=s*cos(t);
    y+=s*sin(t);
    ROS_INFO("ODOM: %f",t);

    geometry_msgs::Quaternion odom_quat = tf::createQuaternionMsgFromYaw(t);
    geometry_msgs::TransformStamped odom_trans;
    ros::Time current_time = ros::Time::now();
    odom_trans.header.stamp = current_time;
    odom_trans.header.frame_id = c.published_odometry_topic.c_str();
    odom_trans.child_frame_id = c.published_link_name.c_str();
    odom_trans.transform.translation.x = x;
    odom_trans.transform.translation.y = y;
    odom_trans.transform.translation.z = 0.0;
    odom_trans.transform.rotation = odom_quat;
    odom_broadcaster.sendTransform(odom_trans);
    nav_msgs::Odometry odom;
    odom.header.stamp = current_time;
    odom.header.frame_id = c.published_odom_link_name;
    odom.pose.pose.position.x = x;
    odom.pose.pose.position.y = y;
    odom.pose.pose.position.z = 0.0;
    odom.pose.pose.orientation = odom_quat;
    odom_pub.publish(odom);
    }

}

void EchoParameters(){
    printf("%s %s\n","_published_ticks_topic",c.published_ticks_topic.c_str());
    printf("%s %s\n","_published_joint_ticks_topic",c.published_joint_ticks_topic.c_str());
    printf("%s %s\n","_subscribed_ticks_topic",c.subscribed_ticks_topic.c_str());
    printf("%s %s\n","_serial_device",c.serial_device.c_str());
    printf("%s %s\n","_published_odometry_topic",c.published_odometry_topic.c_str());
    printf("%s %s\n","_published_link_name",c.published_link_name.c_str());
    printf("%s %s\n","_published_odom_link_name",c.published_odom_link_name.c_str());
    printf("%s %f\n","_kleft",c.kleft);
    printf("%s %f\n","_kright",c.kright);
    printf("%s %f\n","_baseline",c.kbaseline);
    printf("%s %d\n","_ascii",c.ascii);
    printf("%s %d\n","_debug",c.debug);
    printf("%s %d\n","_hearbeat",c.heartbeat);
}

int main(int argc, char **argv)
{
    ros::init(argc, argv, "capybarauno_node",ros::init_options::AnonymousName);
    tf::TransformBroadcaster odom_broadcaster;
    ros::NodeHandle n("~");
    n.param<string>("serial_device", c.serial_device, "/dev/ttyACM0");
    n.param<string>("published_ticks_topic", c.published_ticks_topic, "/robot_ticks");
    n.param<string>("published_joint_ticks_topic", c.published_joint_ticks_topic, "/joint_robot_ticks");
    n.param<string>("cmdvel_topic", c.cmdvel_topic, "/cmd_vel");
    n.param<string>("published_odometry_topic", c.published_odometry_topic, "/odom");
    n.param<string>("published_link_name", c.published_link_name, "/base_link");
    n.param<string>("published_odom_link_name", c.published_odom_link_name, "/odom");
    n.param<double>("kleft", c.kleft, 0.0058);
    n.param<double>("kright", c.kright, 0.0058);
    n.param<double>("kbaseline", c.kbaseline, 0.2);
    n.param<int>("ascii", c.ascii, 1);
    n.param<int>("heartbeat", c.heartbeat, 1);
    n.param("debug", c.debug, 1);

    EchoParameters();
    RobotCommunication_init();

    heartbeat.beat=1;
    heartbeat_packet.id=Heartbeat_Payload_ID;
    heartbeat_packet.seq=0;
    heartbeat_packet.heartbeat=heartbeat;

    previousTicks.leftEncoder=0;
    previousTicks.rightEncoder=0;
    currentTicks.leftEncoder=0;
    currentTicks.rightEncoder=0;
    ros::Subscriber cmdvel_subscriber = n.subscribe(c.cmdvel_topic.c_str(), 1000, cmdvelCallback);
    ticks_publisher = n.advertise<capybarauno::capybara_ticks>(c.published_ticks_topic.c_str(), 1000);
    joint_ticks_publisher = n.advertise<sensor_msgs::JointState>(c.published_joint_ticks_topic.c_str(), 1000);
    odom_pub = n.advertise<nav_msgs::Odometry>(c.published_odometry_topic.c_str(), 1000);
    //ros::ok() used to get the SIGINT ctrl+c
    while(ros::ok()){
        Packet robot_data = read_ticks_from_uart(serialFd,packet_decoder);
        capybarauno::capybara_ticks currentTicks;
        sensor_msgs::JointState currentJointTicks;
        currentTicks.header.seq = robot_data.seq;
        currentTicks.header.stamp = ros::Time::now();
        currentTicks.leftEncoder = robot_data.state.leftEncoder;
        currentTicks.rightEncoder = robot_data.state.rightEncoder;
        currentJointTicks.name.resize(4);
        currentJointTicks.position.resize(4);
        currentJointTicks.name[0]="left signed";
        currentJointTicks.name[1]="right signed";
        currentJointTicks.name[2]="left";
        currentJointTicks.name[3]="right";
        currentJointTicks.position[0]=(double)(-(signed int)((_oldLeft-robot_data.state.leftEncoder)));
        currentJointTicks.position[1]=(double)(signed int)(_oldRight-robot_data.state.rightEncoder);
        currentJointTicks.position[2]=(double)robot_data.state.leftEncoder;
        currentJointTicks.position[3]=(double)robot_data.state.rightEncoder;
        _oldLeft = robot_data.state.leftEncoder;
        _oldRight = robot_data.state.rightEncoder;
        joint_ticks_publisher.publish(currentJointTicks);
        ticks_publisher.publish(currentTicks);
        sendOdometry(odom_broadcaster,currentTicks);
        if(c.heartbeat==1){
            send_heartbeat(beatcnt);
        }
        ros::spinOnce();
        usleep(1000);
    }

    return 0;
}

<commit_msg>absolute joint ticks<commit_after>//system stuff
#include <string>
//ros stuff
#include "ros/ros.h"
#include "sensor_msgs/Joy.h"
#include "sensor_msgs/JointState.h"
#include "capybarauno/capybara_ticks.h"
#include "tf/transform_broadcaster.h"
#include "nav_msgs/Odometry.h"
//own stuff
#include "malComm/mal_comm.h"
#include "malComm/mal_primitives.h"

using namespace std;

int serialFd;
int beatcnt=0;
int beatingheart=0;
struct Packet_Decoder packet_decoder;
struct Packet packet;
struct Speed_Payload speedPayload;
struct State_Payload statePayload;
struct Packet heartbeat_packet;
struct Heartbeat_Payload heartbeat;

ros::Publisher ticks_publisher;
ros::Publisher joint_ticks_publisher;
ros::Publisher odom_pub;

capybarauno::capybara_ticks currentTicks;
capybarauno::capybara_ticks previousTicks;

unsigned int _oldLeft=0;
unsigned int _oldRight=0;
double _oldJointLeft=0;
double _oldJointRight=0;
struct configuration{
    string serial_device;
    string published_ticks_topic;
    string published_joint_ticks_topic;
    string cmdvel_topic;
    string subscribed_ticks_topic;
    double kbaseline;
    double kleft;
    double kright;
    string published_odometry_topic;
    string published_link_name;
    string published_odom_link_name;
    int ascii;
    int debug;
    int heartbeat;

};

struct configuration c;
double x,y,t=0;
uint32_t tick_sequence=0;
int firstMessage=1;

void cmdvelCallback(const geometry_msgs::Twist::ConstPtr& twist)
{
    if(!ros::ok()) return;
    //get absolute speed values, expressed in tick per interval
    double translational_velocity = twist->linear.x;
    double rotational_velocity    = -twist->angular.z/(c.kbaseline*2);
    capybarauno::capybara_ticks ct;
    ct.leftEncoder=(uint16_t)((-translational_velocity+rotational_velocity)/(c.kleft*1000));
    ct.rightEncoder=(uint16_t)((translational_velocity+rotational_velocity)/(c.kright*1000));
    //ROS_INFO("CMDVEL %f %f %d %d",twist->linear.x,twist->angular.z,ct.leftEncoder,ct.rightEncoder);
    speedPayload.leftTick=ct.leftEncoder;
    speedPayload.rightTick=ct.rightEncoder;
    packet.speed=speedPayload;
    char buf[255];
    char* pEnd=Packet_write(&packet,buf,c.ascii);
    sendToUart(serialFd,buf,pEnd-buf,0);

}

Packet read_ticks_from_uart(int serialDevice, Packet_Decoder& decoder){
    char chunk;
    int complete=0;
    Packet read_packet;
    while(read(serialDevice, &chunk, 1)>0 && !complete){
        complete = Packet_Decoder_putChar(&decoder,(unsigned char)chunk);
    }
    if(complete){
        Packet_parse(decoder.buffer_start,&read_packet,c.ascii);
    }
    return read_packet;
}

void RobotCommunication_init(){
    initConsts();
    Packet_Decoder_init(&packet_decoder,c.ascii);
    packet.id=Speed_Payload_ID;
    serialFd=openPort((char*)c.serial_device.c_str());
    if(c.debug){
        printf("serial port status: %d\n",serialFd);
        fflush(stdout);
    }
}

void send_heartbeat(int &cnt){
    if(cnt%2==0){
        heartbeat_packet.seq++;
        char heartbuff[255];
        char* pEnd=Packet_write(&heartbeat_packet,heartbuff,c.ascii);
        sendToUart(serialFd,heartbuff,pEnd-heartbuff,0);
//        if(c.debug){
//            printf("SENDING: %s\n",heartbuff);
//            fflush(stdout);
//        }

    }
    cnt++;
}

void sendOdometry(tf::TransformBroadcaster& odom_broadcaster, capybarauno::capybara_ticks ticks){
    uint16_t ult;
    uint16_t urt;
    if(firstMessage){
        previousTicks.leftEncoder=ticks.leftEncoder;
        previousTicks.rightEncoder=ticks.rightEncoder;
        firstMessage=0;
    }
    else{
    ult = ticks.leftEncoder-previousTicks.leftEncoder;
    urt = ticks.rightEncoder-previousTicks.rightEncoder;
    previousTicks.leftEncoder=ticks.leftEncoder;
    previousTicks.rightEncoder=ticks.rightEncoder;
    int16_t lt = (int16_t)ult;
    int16_t rt = (int16_t)urt;

    double left=-(double)lt*c.kleft;
    double right=(double)rt*c.kright;
    double s = (left+right)/2;
    t-=(right-left)/c.kbaseline;
    x+=s*cos(t);
    y+=s*sin(t);
    ROS_INFO("ODOM: %f",t);

    geometry_msgs::Quaternion odom_quat = tf::createQuaternionMsgFromYaw(t);
    geometry_msgs::TransformStamped odom_trans;
    ros::Time current_time = ros::Time::now();
    odom_trans.header.stamp = current_time;
    odom_trans.header.frame_id = c.published_odometry_topic.c_str();
    odom_trans.child_frame_id = c.published_link_name.c_str();
    odom_trans.transform.translation.x = x;
    odom_trans.transform.translation.y = y;
    odom_trans.transform.translation.z = 0.0;
    odom_trans.transform.rotation = odom_quat;
    odom_broadcaster.sendTransform(odom_trans);
    nav_msgs::Odometry odom;
    odom.header.stamp = current_time;
    odom.header.frame_id = c.published_odom_link_name;
    odom.pose.pose.position.x = x;
    odom.pose.pose.position.y = y;
    odom.pose.pose.position.z = 0.0;
    odom.pose.pose.orientation = odom_quat;
    odom_pub.publish(odom);
    }

}

void EchoParameters(){
    printf("%s %s\n","_published_ticks_topic",c.published_ticks_topic.c_str());
    printf("%s %s\n","_published_joint_ticks_topic",c.published_joint_ticks_topic.c_str());
    printf("%s %s\n","_subscribed_ticks_topic",c.subscribed_ticks_topic.c_str());
    printf("%s %s\n","_serial_device",c.serial_device.c_str());
    printf("%s %s\n","_published_odometry_topic",c.published_odometry_topic.c_str());
    printf("%s %s\n","_published_link_name",c.published_link_name.c_str());
    printf("%s %s\n","_published_odom_link_name",c.published_odom_link_name.c_str());
    printf("%s %f\n","_kleft",c.kleft);
    printf("%s %f\n","_kright",c.kright);
    printf("%s %f\n","_baseline",c.kbaseline);
    printf("%s %d\n","_ascii",c.ascii);
    printf("%s %d\n","_debug",c.debug);
    printf("%s %d\n","_hearbeat",c.heartbeat);
}

int main(int argc, char **argv)
{
    ros::init(argc, argv, "capybarauno_node",ros::init_options::AnonymousName);
    tf::TransformBroadcaster odom_broadcaster;
    ros::NodeHandle n("~");
    n.param<string>("serial_device", c.serial_device, "/dev/ttyACM0");
    n.param<string>("published_ticks_topic", c.published_ticks_topic, "/robot_ticks");
    n.param<string>("published_joint_ticks_topic", c.published_joint_ticks_topic, "/joint_robot_ticks");
    n.param<string>("cmdvel_topic", c.cmdvel_topic, "/cmd_vel");
    n.param<string>("published_odometry_topic", c.published_odometry_topic, "/odom");
    n.param<string>("published_link_name", c.published_link_name, "/base_link");
    n.param<string>("published_odom_link_name", c.published_odom_link_name, "/odom");
    n.param<double>("kleft", c.kleft, 0.0058);
    n.param<double>("kright", c.kright, 0.0058);
    n.param<double>("kbaseline", c.kbaseline, 0.2);
    n.param<int>("ascii", c.ascii, 1);
    n.param<int>("heartbeat", c.heartbeat, 1);
    n.param("debug", c.debug, 1);

    EchoParameters();
    RobotCommunication_init();

    heartbeat.beat=1;
    heartbeat_packet.id=Heartbeat_Payload_ID;
    heartbeat_packet.seq=0;
    heartbeat_packet.heartbeat=heartbeat;

    previousTicks.leftEncoder=0;
    previousTicks.rightEncoder=0;
    currentTicks.leftEncoder=0;
    currentTicks.rightEncoder=0;
    ros::Subscriber cmdvel_subscriber = n.subscribe(c.cmdvel_topic.c_str(), 1000, cmdvelCallback);
    ticks_publisher = n.advertise<capybarauno::capybara_ticks>(c.published_ticks_topic.c_str(), 1000);
    joint_ticks_publisher = n.advertise<sensor_msgs::JointState>(c.published_joint_ticks_topic.c_str(), 1000);
    odom_pub = n.advertise<nav_msgs::Odometry>(c.published_odometry_topic.c_str(), 1000);
    //ros::ok() used to get the SIGINT ctrl+c
    while(ros::ok()){
        Packet robot_data = read_ticks_from_uart(serialFd,packet_decoder);
        capybarauno::capybara_ticks currentTicks;
        sensor_msgs::JointState currentJointTicks;
        currentTicks.header.seq = robot_data.seq;
        currentTicks.header.stamp = ros::Time::now();
        currentTicks.leftEncoder = robot_data.state.leftEncoder;
        currentTicks.rightEncoder = robot_data.state.rightEncoder;
        currentJointTicks.name.resize(4);
        currentJointTicks.position.resize(4);
        currentJointTicks.name[0]="left signed";
        currentJointTicks.name[1]="right signed";
        currentJointTicks.name[2]="left";
        currentJointTicks.name[3]="right";
        currentJointTicks.position[0]=(double)(-(signed int)((_oldLeft-robot_data.state.leftEncoder)));
        currentJointTicks.position[1]=(double)(signed int)(_oldRight-robot_data.state.rightEncoder);
        currentJointTicks.position[2]=_oldJointLeft+(double)robot_data.state.leftEncoder;
        currentJointTicks.position[3]=_oldJointRight+(double)robot_data.state.rightEncoder;
        _oldJointLeft = currentJointTicks.position[2];
        _oldJointRight = currentJointTicks.position[3];
        _oldLeft = robot_data.state.leftEncoder;
        _oldRight = robot_data.state.rightEncoder;
        joint_ticks_publisher.publish(currentJointTicks);
        ticks_publisher.publish(currentTicks);
        sendOdometry(odom_broadcaster,currentTicks);
        if(c.heartbeat==1){
            send_heartbeat(beatcnt);
        }
        ros::spinOnce();
        usleep(1000);
    }

    return 0;
}

<|endoftext|>


<commit_before>/*
 The MIT License (MIT)

 Copyright (c) [2016] [BTC.COM]

 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included in
 all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
 */
#include "StatisticsCkb.h"
#include "Utils.h"
#include "utilities_js.hpp"

static std::map<uint64_t /*height*/, double /*rewards*/> height2reword;
static uint64_t lastTipNum = 0;

template <>
double ShareStatsDay<ShareCkb>::getShareReward(const ShareCkb &share) {
  // if share's height existed in map ,return directly.
  if (height2reword.find(share.height()) != height2reword.end()) {
    std::map<uint64_t, double>::iterator iter;
    for (iter = height2reword.begin();
         iter != height2reword.end() && iter->first < share.height();
         iter++) {
      iter = height2reword.erase(iter);
    }
    return height2reword[share.height()];
  }

  string getTipNum =
      "{\"id\" : 2, \"jsonrpc\" : \"2.0\", \"method\" : "
      "\"get_tip_block_number\", \"params\" : []}";
  string response = "", blockHash = "";
  double blockreward = 0.0;
  // wait for N+11 block submited
  if (height2reword.size() == 0 || share.height() + 11 > lastTipNum) {
    for (;;) {
      bool res = blockchainNodeRpcCall(
          rpcUrl_.c_str(), "", getTipNum.c_str(), response);
      if (res) {
        JsonNode r;
        if (JsonNode::parse(
                response.c_str(), response.c_str() + response.length(), r) &&
            std::strtoull(r["result"].str().c_str(), 0, 16) >=
                share.height() + 11) {
          lastTipNum = std::strtoull(r["result"].str().c_str(), 0, 16);
          LOG(INFO) << "share height : " << share.height()
                    << " network height : " << lastTipNum;
          break;
        }
      }
      std::this_thread::sleep_for(std::chrono::milliseconds(3000));
    }
  }
  // get N+11th blockhash
  string getBlockHash = Strings::Format(
      "{ \"id\" : 2, \"jsonrpc\" : \"2.0\",\"method\" : "
      "\"get_header_by_number\", \"params\" : [\"0x%x\"]}",
      share.height() + 11);
  bool res = blockchainNodeRpcCall(
      rpcUrl_.c_str(), "", getBlockHash.c_str(), response);
  if (res) {
    JsonNode r;
    if (JsonNode::parse(
            response.c_str(), response.c_str() + response.length(), r)) {
      blockHash = r["result"]["hash"].str();
      LOG(INFO) << "block height : " << share.height() + 11
                << " block hash : " << blockHash;
    }
  }
  // get N+11th blockRewards
  string getBlockReward = Strings::Format(
      "{ \"id\" : 2, \"jsonrpc\" : \"2.0\",\"method\" : "
      "\"get_cellbase_output_capacity_details\", \"params\" : [\"%s\"]}",
      blockHash.c_str());

  res = blockchainNodeRpcCall(
      rpcUrl_.c_str(), "", getBlockReward.c_str(), response);
  if (res) {
    JsonNode r;
    if (JsonNode::parse(
            response.c_str(), response.c_str() + response.length(), r)) {
      string reward_t = r["result"]["total"].str();
      uint64_t blockreward_t = std::strtoull(reward_t.c_str(), 0, 16);
      blockreward = blockreward_t;
      height2reword.insert({share.height(), blockreward});
    }
  }
  return blockreward;
}

template class ShareStatsDay<ShareCkb>;
<commit_msg>fixed ckb reward<commit_after>/*
 The MIT License (MIT)

 Copyright (c) [2016] [BTC.COM]

 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included in
 all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
 */
#include "StatisticsCkb.h"
#include "Utils.h"
#include "utilities_js.hpp"

static std::map<uint64_t /*height*/, double /*rewards*/> height2reword;
static uint64_t lastTipNum = 0;

template <>
double ShareStatsDay<ShareCkb>::getShareReward(const ShareCkb &share) {
  // if share's height existed in map ,return directly.
  if (height2reword.find(share.height()) != height2reword.end()) {
    std::map<uint64_t, double>::iterator iter;
    for (iter = height2reword.begin(); iter != height2reword.end();) {
      if (iter->first < share.height()) {
        iter = height2reword.erase(iter);
      } else {
        iter++;
      }
    }
    return height2reword[share.height()];
  }

  string getTipNum =
      "{\"id\" : 2, \"jsonrpc\" : \"2.0\", \"method\" : "
      "\"get_tip_block_number\", \"params\" : []}";
  string response = "", blockHash = "";
  double blockreward = 0.0;
  // wait for N+11 block submited
  if (height2reword.size() == 0 || share.height() + 11 > lastTipNum) {
    for (;;) {
      bool res = blockchainNodeRpcCall(
          rpcUrl_.c_str(), "", getTipNum.c_str(), response);
      if (res) {
        JsonNode r;
        if (JsonNode::parse(
                response.c_str(), response.c_str() + response.length(), r) &&
            std::strtoull(r["result"].str().c_str(), 0, 16) >=
                share.height() + 11) {
          lastTipNum = std::strtoull(r["result"].str().c_str(), 0, 16);
          LOG(INFO) << "share height : " << share.height()
                    << " network height : " << lastTipNum;
          break;
        }
      }
      std::this_thread::sleep_for(std::chrono::milliseconds(3000));
    }
  }
  // get N+11th blockhash
  string getBlockHash = Strings::Format(
      "{ \"id\" : 2, \"jsonrpc\" : \"2.0\",\"method\" : "
      "\"get_header_by_number\", \"params\" : [\"0x%x\"]}",
      share.height() + 11);
  bool res = blockchainNodeRpcCall(
      rpcUrl_.c_str(), "", getBlockHash.c_str(), response);
  if (res) {
    JsonNode r;
    if (JsonNode::parse(
            response.c_str(), response.c_str() + response.length(), r)) {
      blockHash = r["result"]["hash"].str();
      LOG(INFO) << "block height : " << share.height() + 11
                << " block hash : " << blockHash;
    }
  }
  // get N+11th blockRewards
  string getBlockReward = Strings::Format(
      "{ \"id\" : 2, \"jsonrpc\" : \"2.0\",\"method\" : "
      "\"get_cellbase_output_capacity_details\", \"params\" : [\"%s\"]}",
      blockHash.c_str());

  res = blockchainNodeRpcCall(
      rpcUrl_.c_str(), "", getBlockReward.c_str(), response);
  if (res) {
    JsonNode r;
    if (JsonNode::parse(
            response.c_str(), response.c_str() + response.length(), r)) {
      string reward_t = r["result"]["total"].str();
      uint64_t blockreward_t = std::strtoull(reward_t.c_str(), 0, 16);
      blockreward = blockreward_t;
      height2reword.insert({share.height(), blockreward});
    }
  }
  return blockreward;
}

template class ShareStatsDay<ShareCkb>;
<|endoftext|>


<commit_before>/*****************************************************************************
*  Copyright 2011 Sergey Shekya,n Victor Agababov
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* *****************************************************************************/

/*****
 * Author: Sergey Shekyan shekyan@gmail.com
 *         Victor Agababov vagababov@gmail.com
 *
 * Slow HTTP attack vulnerability test tool
 *  http://code.google.com/p/slowhttptest/
 *****/
#include "config.h"
#include <limits.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <memory>
#include <cctype>

#include "slowlog.h"
#include "slowhttptest.h"

#define DEFAULT_URL "http://localhost/"

static void usage() {
  printf(
      "\n%s v.%s, a tool to test for slow HTTP "
      "DoS vulnerabilities.\n"
      "Usage:\n"
      "slowtest [-c <number of connections>] [-<h|b>] [-g <generate statistics>]\n"
      "[-i <interval in seconds>] [-l <test duration in seconds>]\n"
      "-o <output file path and/or name>\n"
      "[-r <connections per second>]\n"
      "[-s <value of Content-Length header>] [-t <verb>]\n"
      "[-u <URL>]\n"
      "[-v <verbosity level>] [-x <max length of follow up data>]\n"
      "Options:\n\t"
      "-c connections,  target number of connections\n\t"
      "                 if not specified\n\t"
      "-h or -b,        specify test mode (slow headers or body)\n\t"
      "-g,              generate statistics with socket state changes\n\t"
      "-i seconds,      interval between followup data in seconds\n\t"
      "-l seconds,      target test length in seconds\n\t"
      "-o file,         place statistics output in file.html and file.csv\n\t"
      "-r num,          connection rate (connections per seconds)\n\t"
      "-s bytes,        value of Content-Length header for POST request\n\t"
      "-t verb          verb (defalut to GET for headers and POST for body)\n\t"
      "-u URL,          absolute URL to target, e.g http[s]://foo/bar\n\t"
      "-v level,        verbosity level 0-4: Fatal, Info, Error, Warning, Debug\n\t"
      "-x bytes,        max length of randomized followup data per tick\n"
      , PACKAGE
      , VERSION
      );
}

// global flag to indicite if we need to run
int g_running = true;

void int_handler(int param) {
  g_running = false;
}

using slowhttptest::slowlog_init;
using slowhttptest::slowlog;
using slowhttptest::SlowHTTPTest;
using slowhttptest::SlowTestType;

int main(int argc, char **argv) {

  if (argc < 1) {
    usage();
    return -1;
  }
  char url[1024] = { 0 };
  char path[1024] = { 0 };
  char verb[16] = { 0 };
  // default vaules
  int conn_cnt = 50;
  int content_length = 4096;
  int rate = 50;
  int duration = 240;
  int debug_level = LOG_INFO;
  int interval = 10;
  int max_random_data_len = 128;
  bool  need_stats = false;
  SlowTestType type = slowhttptest::eHeader;
  long tmp;
  char o;
  while((o = getopt(argc, argv, ":hbgc:i:l:o:r:s:t:u:v:x:")) != -1) {
    switch (o) {
      case 'c':
        tmp = strtol(optarg, 0, 10);
        if(tmp && tmp <= 1024) {
          conn_cnt = static_cast<int>(tmp);
        } else {
          usage();
          return -1;
        }
        break;
      case 'h':
        type = slowhttptest::eHeader;
        break;
      case 'g':
        need_stats = true;
        break;
      case 'b':
        type = slowhttptest::ePost;
        break;
      case 'i':
        tmp = strtol(optarg, 0, 10);
        if(tmp && tmp <= INT_MAX) {
          interval = static_cast<int>(tmp);
        } else {
          usage();
          return -1;
        }
        break;
      case 'l':
        tmp = strtol(optarg, 0, 10);
        if(tmp && tmp <= INT_MAX) {
          duration = static_cast<int>(tmp);
        } else {
          usage();
          return -1;
        }
        break;
      case 'o':
        strncpy(path, optarg, 1023);
        break;
      case 'r':
        tmp = strtol(optarg, 0, 10);
        if(tmp && tmp <= INT_MAX) {
          rate = static_cast<int>(tmp);
        } else {
          usage();
          return -1;
        }
        break;
      case 's':
        tmp = strtol(optarg, 0, 10);
        if(tmp && tmp <= INT_MAX) {
          content_length = static_cast<int>(tmp);
        } else {
          usage();
          return -1;
        }
        break;
      case 't':
        strncpy(verb, optarg, 15);
        break;
      case 'u':
        strncpy(url, optarg, 1023);
        break;
      case 'v':
        tmp = strtol(optarg, 0, 10);
        if(0 <= tmp && tmp <= 4) {
          debug_level = static_cast<int>(tmp);
        } else {
          debug_level = LOG_FATAL;
        }
        break;
      case 'x':
        tmp = strtol(optarg, 0, 10);
        if(tmp && tmp <= INT_MAX) {
          max_random_data_len = static_cast<int>(tmp);
          if(max_random_data_len < 2) max_random_data_len = 2;
        } else {
          usage();
          return -1;
        }
        break;
      case '?':
        fprintf(stderr, "Illegal option -%c\n", optopt);
        usage();
        return -1;
        break;
      default:
        fprintf(stderr, "Option -%c requires an argument.\n", optopt);
        usage();
        return -1;
    }
  }
  if(!strlen(url)) {
    strncpy(url, DEFAULT_URL, sizeof(DEFAULT_URL));
  }
  signal(SIGPIPE, SIG_IGN);
  signal(SIGINT, &int_handler);
  slowlog_init(debug_level, NULL);
  std::auto_ptr<SlowHTTPTest> slow_test(
    new SlowHTTPTest(rate, duration, interval, conn_cnt,
    max_random_data_len, content_length, type, need_stats));
  if(!slow_test->init(url, verb, path)) {
    slowlog(LOG_FATAL, "%s: error setting up slow HTTP test\n", __FUNCTION__);
    return -1;
  } else if(!slow_test->run_test()) {
    slowlog(LOG_FATAL, "%s: error running slow HTTP test\n", __FUNCTION__);
    return -1;
  }
  slow_test->report_final();
  return 0;
}
<commit_msg>removed unnecessary stuff<commit_after>/*****************************************************************************
*  Copyright 2011 Sergey Shekya,n Victor Agababov
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* *****************************************************************************/

/*****
 * Author: Sergey Shekyan shekyan@gmail.com
 *         Victor Agababov vagababov@gmail.com
 *
 * Slow HTTP attack vulnerability test tool
 *  http://code.google.com/p/slowhttptest/
 *****/
#include "config.h"
#include <limits.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <memory>
#include <cctype>

#include "slowlog.h"
#include "slowhttptest.h"

#define DEFAULT_URL "http://localhost/"

static void usage() {
  printf(
      "\n%s v.%s, a tool to test for slow HTTP "
      "DoS vulnerabilities.\n"
      "Usage:\n"
      "slowtest [-c <number of connections>] [-<h|b>] [-g <generate statistics>]\n"
      "[-i <interval in seconds>] [-l <test duration in seconds>]\n"
      "-o <output file path and/or name>\n"
      "[-r <connections per second>]\n"
      "[-s <value of Content-Length header>] [-t <verb>]\n"
      "[-u <URL>]\n"
      "[-v <verbosity level>] [-x <max length of follow up data>]\n"
      "Options:\n\t"
      "-c connections,  target number of connections\n\t"
      "-h or -b,        specify test mode (slow headers or body)\n\t"
      "-g,              generate statistics with socket state changes\n\t"
      "-i seconds,      interval between followup data in seconds\n\t"
      "-l seconds,      target test length in seconds\n\t"
      "-o file,         place statistics output in file.html and file.csv\n\t"
      "-r num,          connection rate (connections per seconds)\n\t"
      "-s bytes,        value of Content-Length header for POST request\n\t"
      "-t verb          verb (defalut to GET for headers and POST for body)\n\t"
      "-u URL,          absolute URL to target, e.g http[s]://foo/bar\n\t"
      "-v level,        verbosity level 0-4: Fatal, Info, Error, Warning, Debug\n\t"
      "-x bytes,        max length of randomized followup data per tick\n"
      , PACKAGE
      , VERSION
      );
}

// global flag to indicite if we need to run
int g_running = true;

void int_handler(int param) {
  g_running = false;
}

using slowhttptest::slowlog_init;
using slowhttptest::slowlog;
using slowhttptest::SlowHTTPTest;
using slowhttptest::SlowTestType;

int main(int argc, char **argv) {

  if (argc < 1) {
    usage();
    return -1;
  }
  char url[1024] = { 0 };
  char path[1024] = { 0 };
  char verb[16] = { 0 };
  // default vaules
  int conn_cnt = 50;
  int content_length = 4096;
  int rate = 50;
  int duration = 240;
  int debug_level = LOG_INFO;
  int interval = 10;
  int max_random_data_len = 128;
  bool  need_stats = false;
  SlowTestType type = slowhttptest::eHeader;
  long tmp;
  char o;
  while((o = getopt(argc, argv, ":hbgc:i:l:o:r:s:t:u:v:x:")) != -1) {
    switch (o) {
      case 'c':
        tmp = strtol(optarg, 0, 10);
        if(tmp && tmp <= 1024) {
          conn_cnt = static_cast<int>(tmp);
        } else {
          usage();
          return -1;
        }
        break;
      case 'h':
        type = slowhttptest::eHeader;
        break;
      case 'g':
        need_stats = true;
        break;
      case 'b':
        type = slowhttptest::ePost;
        break;
      case 'i':
        tmp = strtol(optarg, 0, 10);
        if(tmp && tmp <= INT_MAX) {
          interval = static_cast<int>(tmp);
        } else {
          usage();
          return -1;
        }
        break;
      case 'l':
        tmp = strtol(optarg, 0, 10);
        if(tmp && tmp <= INT_MAX) {
          duration = static_cast<int>(tmp);
        } else {
          usage();
          return -1;
        }
        break;
      case 'o':
        strncpy(path, optarg, 1023);
        break;
      case 'r':
        tmp = strtol(optarg, 0, 10);
        if(tmp && tmp <= INT_MAX) {
          rate = static_cast<int>(tmp);
        } else {
          usage();
          return -1;
        }
        break;
      case 's':
        tmp = strtol(optarg, 0, 10);
        if(tmp && tmp <= INT_MAX) {
          content_length = static_cast<int>(tmp);
        } else {
          usage();
          return -1;
        }
        break;
      case 't':
        strncpy(verb, optarg, 15);
        break;
      case 'u':
        strncpy(url, optarg, 1023);
        break;
      case 'v':
        tmp = strtol(optarg, 0, 10);
        if(0 <= tmp && tmp <= 4) {
          debug_level = static_cast<int>(tmp);
        } else {
          debug_level = LOG_FATAL;
        }
        break;
      case 'x':
        tmp = strtol(optarg, 0, 10);
        if(tmp && tmp <= INT_MAX) {
          max_random_data_len = static_cast<int>(tmp);
          if(max_random_data_len < 2) max_random_data_len = 2;
        } else {
          usage();
          return -1;
        }
        break;
      case '?':
        fprintf(stderr, "Illegal option -%c\n", optopt);
        usage();
        return -1;
        break;
      default:
        fprintf(stderr, "Option -%c requires an argument.\n", optopt);
        usage();
        return -1;
    }
  }
  if(!strlen(url)) {
    strncpy(url, DEFAULT_URL, sizeof(DEFAULT_URL));
  }
  signal(SIGPIPE, SIG_IGN);
  signal(SIGINT, &int_handler);
  slowlog_init(debug_level, NULL);
  std::auto_ptr<SlowHTTPTest> slow_test(
    new SlowHTTPTest(rate, duration, interval, conn_cnt,
    max_random_data_len, content_length, type, need_stats));
  if(!slow_test->init(url, verb, path)) {
    slowlog(LOG_FATAL, "%s: error setting up slow HTTP test\n", __FUNCTION__);
    return -1;
  } else if(!slow_test->run_test()) {
    slowlog(LOG_FATAL, "%s: error running slow HTTP test\n", __FUNCTION__);
    return -1;
  }
  slow_test->report_final();
  return 0;
}
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2015 - The CM Authors <legal@clickmatcher.com>
 *   All Rights Reserved.
 *
 * This file is CONFIDENTIAL -- Distribution or duplication of this material or
 * the information contained herein is strictly forbidden unless prior written
 * permission is obtained.
 */
#include <fnord-base/stdtypes.h>
#include <fnord-base/cli/flagparser.h>
#include <fnord-base/application.h>
#include <fnord-base/logging.h>
#include <fnord-base/random.h>
#include <fnord-base/wallclock.h>
#include <fnord-base/thread/eventloop.h>
#include <fnord-base/thread/threadpool.h>
#include <fnord-http/httpconnectionpool.h>
#include <fnord-dproc/Application.h>
#include <fnord-dproc/LocalScheduler.h>
#include <fnord-tsdb/TSDBClient.h>
#include "analytics/ItemBoostMapper.h"
#include "analytics/ItemBoostMerge.h"
#include "analytics/ItemBoostExport.h"
#include "analytics/ProtoSSTableMergeReducer.h"

using namespace fnord;
using namespace cm;

fnord::thread::EventLoop ev;

int main(int argc, const char** argv) {
  fnord::Application::init();
  fnord::Application::logToStderr();

  fnord::cli::FlagParser flags;

  flags.defineFlag(
      "output",
      cli::FlagParser::T_STRING,
      false,
      NULL,
      NULL,
      "output file",
      "<path>");

  flags.defineFlag(
      "tempdir",
      cli::FlagParser::T_STRING,
      false,
      NULL,
      NULL,
      "artifact directory",
      "<path>");

  flags.defineFlag(
      "loglevel",
      fnord::cli::FlagParser::T_STRING,
      false,
      NULL,
      "INFO",
      "loglevel",
      "<level>");

  flags.parseArgv(argc, argv);

  Logger::get()->setMinimumLogLevel(
      strToLogLevel(flags.getString("loglevel")));

  /* start event loop */
  auto evloop_thread = std::thread([] {
    ev.run();
  });

  http::HTTPConnectionPool http(&ev);
  tsdb::TSDBClient tsdb("http://nue03.prod.fnrd.net:7003/tsdb", &http);

  dproc::Application app("cm.itemboost");

  app.registerProtoTaskFactory<AnalyticsTableScanMapperParams>(
      "ItemBoostMapper",
      [&tsdb] (const AnalyticsTableScanMapperParams& params)
          -> RefPtr<dproc::Task> {
        auto report = new ItemBoostMapper(
            new AnalyticsTableScanSource(params, &tsdb),
            new ProtoSSTableSink<ItemBoostRow>());

        report->setCacheKey(
            "cm.itemboost~" + report->input()->cacheKey());

        return report;
      });

  app.registerProtoTaskFactory<AnalyticsTableScanReducerParams>(
      "ItemBoostReducer",
      [&tsdb] (const AnalyticsTableScanReducerParams& params)
          -> RefPtr<dproc::Task> {
        auto stream = "joined_sessions." + params.customer();
        auto partitions = tsdb.listPartitions(
            stream,
            params.from_unixmicros(),
            params.until_unixmicros());

        List<dproc::TaskDependency> map_chunks;
        for (const auto& part : partitions) {
          AnalyticsTableScanMapperParams map_chunk_params;
          map_chunk_params.set_stream_key(stream);
          map_chunk_params.set_partition_key(part);

          map_chunks.emplace_back(dproc::TaskDependency {
            .task_name = "ItemBoostMapper",
            .params = *msg::encode(map_chunk_params)
          });
        }

        return new ProtoSSTableMergeReducer<ItemBoostRow>(
            new ProtoSSTableSource<ItemBoostRow>(map_chunks),
            new ProtoSSTableSink<ItemBoostRow>(),
            std::bind(
                &ItemBoostMerge::merge,
                std::placeholders::_1,
                std::placeholders::_2));
      });

  app.registerTaskFactory(
      "ItemBoostExport",
      [&tsdb] (const Buffer& params)
          -> RefPtr<dproc::Task> {
        List<dproc::TaskDependency> deps;
        deps.emplace_back(dproc::TaskDependency {
          .task_name = "ItemBoostReducer",
          .params = params
        });

        return new ItemBoostExport(
            new ProtoSSTableSource<ItemBoostRow>(deps),
            new CSVSink());
      });

  dproc::LocalScheduler sched(flags.getString("tempdir"));
  sched.start();

  AnalyticsTableScanReducerParams params;
  params.set_customer("dawanda");
  params.set_from_unixmicros(WallClock::unixMicros() - 30 * kMicrosPerDay);
  params.set_until_unixmicros(WallClock::unixMicros() - 2 * kMicrosPerDay);

  auto res = sched.run(&app, "ItemBoostExport", *msg::encode(params));

  auto output_file = File::openFile(
      flags.getString("output"),
      File::O_CREATEOROPEN | File::O_WRITE);

  output_file.write(res->data(), res->size());

  sched.stop();
  ev.shutdown();
  evloop_thread.join();
  exit(0);
}

<commit_msg>--threads flag<commit_after>/**
 * Copyright (c) 2015 - The CM Authors <legal@clickmatcher.com>
 *   All Rights Reserved.
 *
 * This file is CONFIDENTIAL -- Distribution or duplication of this material or
 * the information contained herein is strictly forbidden unless prior written
 * permission is obtained.
 */
#include <fnord-base/stdtypes.h>
#include <fnord-base/cli/flagparser.h>
#include <fnord-base/application.h>
#include <fnord-base/logging.h>
#include <fnord-base/random.h>
#include <fnord-base/wallclock.h>
#include <fnord-base/thread/eventloop.h>
#include <fnord-base/thread/threadpool.h>
#include <fnord-http/httpconnectionpool.h>
#include <fnord-dproc/Application.h>
#include <fnord-dproc/LocalScheduler.h>
#include <fnord-tsdb/TSDBClient.h>
#include "analytics/ItemBoostMapper.h"
#include "analytics/ItemBoostMerge.h"
#include "analytics/ItemBoostExport.h"
#include "analytics/ProtoSSTableMergeReducer.h"

using namespace fnord;
using namespace cm;

fnord::thread::EventLoop ev;

int main(int argc, const char** argv) {
  fnord::Application::init();
  fnord::Application::logToStderr();

  fnord::cli::FlagParser flags;

  flags.defineFlag(
      "output",
      cli::FlagParser::T_STRING,
      false,
      NULL,
      NULL,
      "output file",
      "<path>");

  flags.defineFlag(
      "tempdir",
      cli::FlagParser::T_STRING,
      false,
      NULL,
      NULL,
      "artifact directory",
      "<path>");

  flags.defineFlag(
      "threads",
      cli::FlagParser::T_INTEGER,
      true,
      NULL,
      "8",
      "nthreads",
      "<num>");

  flags.defineFlag(
      "loglevel",
      fnord::cli::FlagParser::T_STRING,
      false,
      NULL,
      "INFO",
      "loglevel",
      "<level>");

  flags.parseArgv(argc, argv);

  Logger::get()->setMinimumLogLevel(
      strToLogLevel(flags.getString("loglevel")));

  /* start event loop */
  auto evloop_thread = std::thread([] {
    ev.run();
  });

  http::HTTPConnectionPool http(&ev);
  tsdb::TSDBClient tsdb("http://nue03.prod.fnrd.net:7003/tsdb", &http);

  dproc::Application app("cm.itemboost");

  app.registerProtoTaskFactory<AnalyticsTableScanMapperParams>(
      "ItemBoostMapper",
      [&tsdb] (const AnalyticsTableScanMapperParams& params)
          -> RefPtr<dproc::Task> {
        auto report = new ItemBoostMapper(
            new AnalyticsTableScanSource(params, &tsdb),
            new ProtoSSTableSink<ItemBoostRow>());

        report->setCacheKey(
            "cm.itemboost~" + report->input()->cacheKey());

        return report;
      });

  app.registerProtoTaskFactory<AnalyticsTableScanReducerParams>(
      "ItemBoostReducer",
      [&tsdb] (const AnalyticsTableScanReducerParams& params)
          -> RefPtr<dproc::Task> {
        auto stream = "joined_sessions." + params.customer();
        auto partitions = tsdb.listPartitions(
            stream,
            params.from_unixmicros(),
            params.until_unixmicros());

        List<dproc::TaskDependency> map_chunks;
        for (const auto& part : partitions) {
          AnalyticsTableScanMapperParams map_chunk_params;
          map_chunk_params.set_stream_key(stream);
          map_chunk_params.set_partition_key(part);

          map_chunks.emplace_back(dproc::TaskDependency {
            .task_name = "ItemBoostMapper",
            .params = *msg::encode(map_chunk_params)
          });
        }

        return new ProtoSSTableMergeReducer<ItemBoostRow>(
            new ProtoSSTableSource<ItemBoostRow>(map_chunks),
            new ProtoSSTableSink<ItemBoostRow>(),
            std::bind(
                &ItemBoostMerge::merge,
                std::placeholders::_1,
                std::placeholders::_2));
      });

  app.registerTaskFactory(
      "ItemBoostExport",
      [&tsdb] (const Buffer& params)
          -> RefPtr<dproc::Task> {
        List<dproc::TaskDependency> deps;
        deps.emplace_back(dproc::TaskDependency {
          .task_name = "ItemBoostReducer",
          .params = params
        });

        return new ItemBoostExport(
            new ProtoSSTableSource<ItemBoostRow>(deps),
            new CSVSink());
      });

  dproc::LocalScheduler sched(flags.getString("tempdir"), flags.getInt("threads"));
  sched.start();

  AnalyticsTableScanReducerParams params;
  params.set_customer("dawanda");
  params.set_from_unixmicros(WallClock::unixMicros() - 30 * kMicrosPerDay);
  params.set_until_unixmicros(WallClock::unixMicros() - 2 * kMicrosPerDay);

  auto res = sched.run(&app, "ItemBoostExport", *msg::encode(params));

  auto output_file = File::openFile(
      flags.getString("output"),
      File::O_CREATEOROPEN | File::O_WRITE);

  output_file.write(res->data(), res->size());

  sched.stop();
  ev.shutdown();
  evloop_thread.join();
  exit(0);
}

<|endoftext|>


<commit_before>/**
 * Copyright (c) 2015 - The CM Authors <legal@clickmatcher.com>
 *   All Rights Reserved.
 *
 * This file is CONFIDENTIAL -- Distribution or duplication of this material or
 * the information contained herein is strictly forbidden unless prior written
 * permission is obtained.
 */
#include <algorithm>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include "fnord-base/io/fileutil.h"
#include "fnord-base/thread/eventloop.h"
#include "fnord-base/application.h"
#include "fnord-base/logging.h"
#include "fnord-base/Language.h"
#include "fnord-base/random.h"
#include "fnord-base/fnv.h"
#include "fnord-base/cli/flagparser.h"
#include "fnord-base/util/SimpleRateLimit.h"
#include "fnord-base/InternMap.h"
#include "fnord-base/thread/threadpool.h"
#include "fnord-dproc/Application.h"
#include "fnord-dproc/LocalScheduler.h"
#include "fnord-json/json.h"
#include "fnord-mdb/MDB.h"
#include "fnord-mdb/MDBUtil.h"
#include "fnord-sstable/sstablereader.h"
#include "fnord-sstable/sstablewriter.h"
#include "fnord-sstable/SSTableColumnSchema.h"
#include "fnord-sstable/SSTableColumnReader.h"
#include "fnord-sstable/SSTableColumnWriter.h"
#include "fnord-http/httpconnectionpool.h"
#include <fnord-fts/fts.h>
#include <fnord-fts/fts_common.h>
#include "fnord-logtable/TableReader.h"
#include "common.h"
#include "schemas.h"
#include "CustomerNamespace.h"
#include "CTRCounter.h"
#include "analytics/ReportBuilder.h"
#include "analytics/AnalyticsTableScanSource.h"
#include "analytics/CTRByShopMapper.h"
#include "analytics/ECommerceStatsByShopMapper.h"
#include "analytics/ProductStatsByShopMapper.h"
#include "analytics/CTRCounterMergeReducer.h"
#include "AnalyticsTableScanParams.pb.h"

using namespace fnord;
using namespace cm;

fnord::thread::EventLoop ev;

int main(int argc, const char** argv) {
  fnord::Application::init();
  fnord::Application::logToStderr();

  fnord::cli::FlagParser flags;

  flags.defineFlag(
      "output",
      cli::FlagParser::T_STRING,
      false,
      NULL,
      NULL,
      "output file",
      "<path>");

  flags.defineFlag(
      "tempdir",
      cli::FlagParser::T_STRING,
      false,
      NULL,
      NULL,
      "artifact directory",
      "<path>");

  flags.defineFlag(
      "loglevel",
      fnord::cli::FlagParser::T_STRING,
      false,
      NULL,
      "INFO",
      "loglevel",
      "<level>");

  flags.parseArgv(argc, argv);

  Logger::get()->setMinimumLogLevel(
      strToLogLevel(flags.getString("loglevel")));

  /* start event loop */
  auto evloop_thread = std::thread([] {
    ev.run();
  });

  http::HTTPConnectionPool http(&ev);
  tsdb::TSDBClient tsdb("http://nue03.prod.fnrd.net:7003/tsdb", &http);

  dproc::Application app("cm.shopstats");

  app.registerProtoTaskFactory<AnalyticsTableScanMapperParams>(
      "CTRByShopMapper",
      [&tsdb] (const AnalyticsTableScanMapperParams& params)
          -> RefPtr<dproc::Task> {
        auto report = new CTRByShopMapper(
            new AnalyticsTableScanSource(params, &tsdb),
            new ShopStatsTableSink());

        report->setCacheKey(
            "cm.shopstats.ctr~" + report->input()->cacheKey());

        return report;
      });

  app.registerProtoTaskFactory<AnalyticsTableScanMapperParams>(
      "EcommerceStatsByShopMapper",
      [&tsdb] (const AnalyticsTableScanMapperParams& params)
          -> RefPtr<dproc::Task> {
        auto report = new ECommerceStatsByShopMapper(
            new AnalyticsTableScanSource(params, &tsdb),
            new ShopStatsTableSink());

        report->setCacheKey(
            "cm.shopstats.ecommerce~" + report->input()->cacheKey());

        return report;
      });

  app.registerProtoTaskFactory<AnalyticsTableScanReducerParams>(
      "ShopStatsReducer",
      [&tsdb] (const AnalyticsTableScanReducerParams& params)
          -> RefPtr<dproc::Task> {
        auto stream = "joined_sessions." + params.customer();
        auto partitions = tsdb.listPartitions(
            stream,
            params.from_unixmicros(),
            params.until_unixmicros());

        List<dproc::TaskDependency> map_chunks;
        for (const auto& part : partitions) {
          AnalyticsTableScanMapperParams map_chunk_params;
          map_chunk_params.set_stream_key(stream);
          map_chunk_params.set_partition_key(part);

          map_chunks.emplace_back(dproc::TaskDependency {
            .task_name = "CTRByShopMapper",
            .params = *msg::encode(map_chunk_params)
          });

          map_chunks.emplace_back(dproc::TaskDependency {
            .task_name = "EcommerceStatsByShopMapper",
            .params = *msg::encode(map_chunk_params)
          });
        }

        return new ShopStatsMergeReducer(
            new ShopStatsTableSource(map_chunks),
            new ShopStatsTableSink());
      });

  dproc::LocalScheduler sched(flags.getString("tempdir"));
  sched.start();

  AnalyticsTableScanReducerParams params;
  params.set_customer("dawanda");
  params.set_from_unixmicros(WallClock::unixMicros() - 3 * kMicrosPerDay);
  params.set_until_unixmicros(WallClock::unixMicros() - 2 * kMicrosPerDay);

  auto res = sched.run(&app, "ShopStatsReducer", *msg::encode(params));

  auto output_file = File::openFile(
      flags.getString("output"),
      File::O_CREATEOROPEN | File::O_WRITE);

  output_file.write(res->data(), res->size());

  sched.stop();
  ev.shutdown();
  evloop_thread.join();

  exit(0);
}

<commit_msg>last 30 days<commit_after>/**
 * Copyright (c) 2015 - The CM Authors <legal@clickmatcher.com>
 *   All Rights Reserved.
 *
 * This file is CONFIDENTIAL -- Distribution or duplication of this material or
 * the information contained herein is strictly forbidden unless prior written
 * permission is obtained.
 */
#include <algorithm>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include "fnord-base/io/fileutil.h"
#include "fnord-base/thread/eventloop.h"
#include "fnord-base/application.h"
#include "fnord-base/logging.h"
#include "fnord-base/Language.h"
#include "fnord-base/random.h"
#include "fnord-base/fnv.h"
#include "fnord-base/cli/flagparser.h"
#include "fnord-base/util/SimpleRateLimit.h"
#include "fnord-base/InternMap.h"
#include "fnord-base/thread/threadpool.h"
#include "fnord-dproc/Application.h"
#include "fnord-dproc/LocalScheduler.h"
#include "fnord-json/json.h"
#include "fnord-mdb/MDB.h"
#include "fnord-mdb/MDBUtil.h"
#include "fnord-sstable/sstablereader.h"
#include "fnord-sstable/sstablewriter.h"
#include "fnord-sstable/SSTableColumnSchema.h"
#include "fnord-sstable/SSTableColumnReader.h"
#include "fnord-sstable/SSTableColumnWriter.h"
#include "fnord-http/httpconnectionpool.h"
#include <fnord-fts/fts.h>
#include <fnord-fts/fts_common.h>
#include "fnord-logtable/TableReader.h"
#include "common.h"
#include "schemas.h"
#include "CustomerNamespace.h"
#include "CTRCounter.h"
#include "analytics/ReportBuilder.h"
#include "analytics/AnalyticsTableScanSource.h"
#include "analytics/CTRByShopMapper.h"
#include "analytics/ECommerceStatsByShopMapper.h"
#include "analytics/ProductStatsByShopMapper.h"
#include "analytics/CTRCounterMergeReducer.h"
#include "AnalyticsTableScanParams.pb.h"

using namespace fnord;
using namespace cm;

fnord::thread::EventLoop ev;

int main(int argc, const char** argv) {
  fnord::Application::init();
  fnord::Application::logToStderr();

  fnord::cli::FlagParser flags;

  flags.defineFlag(
      "output",
      cli::FlagParser::T_STRING,
      false,
      NULL,
      NULL,
      "output file",
      "<path>");

  flags.defineFlag(
      "tempdir",
      cli::FlagParser::T_STRING,
      false,
      NULL,
      NULL,
      "artifact directory",
      "<path>");

  flags.defineFlag(
      "loglevel",
      fnord::cli::FlagParser::T_STRING,
      false,
      NULL,
      "INFO",
      "loglevel",
      "<level>");

  flags.parseArgv(argc, argv);

  Logger::get()->setMinimumLogLevel(
      strToLogLevel(flags.getString("loglevel")));

  /* start event loop */
  auto evloop_thread = std::thread([] {
    ev.run();
  });

  http::HTTPConnectionPool http(&ev);
  tsdb::TSDBClient tsdb("http://nue03.prod.fnrd.net:7003/tsdb", &http);

  dproc::Application app("cm.shopstats");

  app.registerProtoTaskFactory<AnalyticsTableScanMapperParams>(
      "CTRByShopMapper",
      [&tsdb] (const AnalyticsTableScanMapperParams& params)
          -> RefPtr<dproc::Task> {
        auto report = new CTRByShopMapper(
            new AnalyticsTableScanSource(params, &tsdb),
            new ShopStatsTableSink());

        report->setCacheKey(
            "cm.shopstats.ctr~" + report->input()->cacheKey());

        return report;
      });

  app.registerProtoTaskFactory<AnalyticsTableScanMapperParams>(
      "EcommerceStatsByShopMapper",
      [&tsdb] (const AnalyticsTableScanMapperParams& params)
          -> RefPtr<dproc::Task> {
        auto report = new ECommerceStatsByShopMapper(
            new AnalyticsTableScanSource(params, &tsdb),
            new ShopStatsTableSink());

        report->setCacheKey(
            "cm.shopstats.ecommerce~" + report->input()->cacheKey());

        return report;
      });

  app.registerProtoTaskFactory<AnalyticsTableScanReducerParams>(
      "ShopStatsReducer",
      [&tsdb] (const AnalyticsTableScanReducerParams& params)
          -> RefPtr<dproc::Task> {
        auto stream = "joined_sessions." + params.customer();
        auto partitions = tsdb.listPartitions(
            stream,
            params.from_unixmicros(),
            params.until_unixmicros());

        List<dproc::TaskDependency> map_chunks;
        for (const auto& part : partitions) {
          AnalyticsTableScanMapperParams map_chunk_params;
          map_chunk_params.set_stream_key(stream);
          map_chunk_params.set_partition_key(part);

          map_chunks.emplace_back(dproc::TaskDependency {
            .task_name = "CTRByShopMapper",
            .params = *msg::encode(map_chunk_params)
          });

          map_chunks.emplace_back(dproc::TaskDependency {
            .task_name = "EcommerceStatsByShopMapper",
            .params = *msg::encode(map_chunk_params)
          });
        }

        return new ShopStatsMergeReducer(
            new ShopStatsTableSource(map_chunks),
            new ShopStatsTableSink());
      });

  dproc::LocalScheduler sched(flags.getString("tempdir"));
  sched.start();

  AnalyticsTableScanReducerParams params;
  params.set_customer("dawanda");
  params.set_from_unixmicros(WallClock::unixMicros() - 30 * kMicrosPerDay);
  params.set_until_unixmicros(WallClock::unixMicros() - 2 * kMicrosPerDay);

  auto res = sched.run(&app, "ShopStatsReducer", *msg::encode(params));

  auto output_file = File::openFile(
      flags.getString("output"),
      File::O_CREATEOROPEN | File::O_WRITE);

  output_file.write(res->data(), res->size());

  sched.stop();
  ev.shutdown();
  evloop_thread.join();

  exit(0);
}

<|endoftext|>