cyphesis/tools/EntityExporter.cpp
Erik Ogenvik 4411d3a14f Added "cyexport" tool for exporting.
This uses the same exporting code as Ember, and allows for export of
both entities, minds and types. The code in EntityExporterBase.* should
be kept synchronized with the Ember version.
This is provided as a new command, instead of added to the existing
cycmd executable. This is by design, to make it easier for users. Export
and import of entities are one of the most basic functions, especially
for any new user, and should therefore be provided as easy as
possible.
2013-11-14 22:21:06 +01:00

170 lines
4.7 KiB
C++

//
// Copyright (C) 2009 Alistair Riddoch
// Copyright (C) 2012 Erik Ogenvik
//
// 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 2 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, write to the Free Software Foundation,
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#include "EntityExporter.h"
#include "MultiLineListFormatter.h"
#include "common/serialno.h"
#include "common/log.h"
#include "common/compose.hpp"
#include <Atlas/Objects/Operation.h>
#include <Atlas/Objects/Entity.h>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <sstream>
#include <cassert>
using Atlas::Objects::Root;
using Atlas::Objects::smart_dynamic_cast;
using Atlas::Objects::Entity::Anonymous;
using Atlas::Objects::Entity::RootEntity;
using Atlas::Objects::Operation::Talk;
using Atlas::Objects::Operation::Get;
using Atlas::Message::Element;
using Atlas::Message::ListType;
using Atlas::Message::MapType;
EntityExporter::EntityExporter(const std::string & accountId,
const std::string & avatarId) :
EntityExporterBase(accountId, avatarId, getCurrentTime()), mCurrentRes(
nullptr)
{
assert(accountId != "");
assert(avatarId != "");
}
EntityExporter::~EntityExporter()
{
}
void EntityExporter::setup(const std::string & arg, OpVector & ret)
{
mCurrentRes = &ret;
//Start by asking the server for information about itself
//so we can provide correct meta data in fillWithServerData()
Get get;
get->setObjtype("op");
get->setSerialno(newSerialNumber());
CallbackFunction callback = sigc::mem_fun(*this,
&EntityExporter::operationGetServerInfo);
sendAndAwaitResponse(get, callback);
start(arg, "0");
mCurrentRes = nullptr;
if (mComplete || mCancelled) {
m_complete = true;
}
}
void EntityExporter::operation(const Operation & op, OpVector & res)
{
mCurrentRes = &res;
if (!op->isDefaultRefno()) {
auto I = mCallbacks.find(op->getRefno());
if (I != mCallbacks.end()) {
auto callback = I->second;
mCallbacks.erase(I);
callback(op);
}
} else {
if (op->getClassNo() == Atlas::Objects::Operation::ERROR_NO) {
std::string message =
op->getArgs().front()->getAttr("message").asString();
log(ERROR, String::compose("Got error. Message: %1", message));
}
}
mCurrentRes = nullptr;
if (mComplete || mCancelled) {
m_complete = true;
}
}
long int EntityExporter::newSerialNumber()
{
return newSerialNo();
}
void EntityExporter::send(const Atlas::Objects::Operation::RootOperation& op)
{
if (mCurrentRes) {
mCurrentRes->push_back(op);
}
}
void EntityExporter::sendAndAwaitResponse(
const Atlas::Objects::Operation::RootOperation& op,
CallbackFunction& callback)
{
if (mCurrentRes) {
mCallbacks.insert(std::make_pair(op->getSerialno(), callback));
mCurrentRes->push_back(op);
}
}
Atlas::Formatter* EntityExporter::createMultiLineFormatter(std::iostream& s,
Atlas::Bridge& b)
{
return new MultiLineListFormatter(s, b);
}
std::string EntityExporter::getCurrentTime()
{
boost::posix_time::ptime epoch(boost::gregorian::date(1970, 1, 1));
std::stringstream ss;
ss
<< (boost::posix_time::microsec_clock::universal_time() - epoch).total_milliseconds();
return ss.str();
}
void EntityExporter::fillWithServerData(Atlas::Message::MapType& serverMap)
{
Element e;
if (m_server_info->copyAttr("name", e) == 0 && e.isString()) {
serverMap["name"] = e.asString();
//TODO: get the hostname in a different way
serverMap["host"] = e.asString();
}
if (m_server_info->copyAttr("ruleset", e) == 0 && e.isString()) {
serverMap["ruleset"] = e.asString();
}
if (m_server_info->copyAttr("version", e) == 0 && e.isString()) {
serverMap["version"] = e.asString();
}
if (m_server_info->copyAttr("name", e) == 0 && e.isString()) {
serverMap["name"] = e.asString();
}
}
void EntityExporter::operationGetServerInfo(
const Atlas::Objects::Operation::RootOperation& op)
{
if (!op->getArgs().empty()) {
m_server_info = op->getArgs().front();
}
}