Commit e705419a authored by Tristan Matthews's avatar Tristan Matthews

* #7264: History is read as a list of Dicts

History saving still has to be updated.
parent bb504cce
......@@ -43,16 +43,7 @@
namespace Conf {
ConfigTree::~ConfigTree()
{
// erase every new ItemMap (by CreateSection)
SectionMap::iterator iter = sections_.begin();
while (iter != sections_.end()) {
delete iter->second;
iter->second = NULL;
iter++;
}
}
{}
void ConfigTree::addDefaultValue(const std::pair<std::string, std::string>& token, std::string section)
{
......@@ -81,7 +72,7 @@ ConfigTree::createSection(const std::string& section)
{
// if we doesn't find the item, create it
if (sections_.find(section) == sections_.end())
sections_[section] = new ItemMap;
sections_[section] = ItemMap();
}
/**
......@@ -98,18 +89,13 @@ ConfigTree::removeSection(const std::string& section)
}
/** Retrieve the sections as an array */
TokenList
std::list<std::string>
ConfigTree::getSections()
{
TokenList sections;
SectionMap::iterator iter = sections_.begin();
std::list<std::string> sections;
while (iter != sections_.end()) {
// add to token list the: iter->second;
for (SectionMap::iterator iter = sections_.begin(); iter != sections_.end(); ++iter)
sections.push_back(iter->first);
iter++;
}
return sections;
}
......@@ -125,7 +111,7 @@ ConfigTree::addConfigTreeItem(const std::string& section, const ConfigTreeItem i
SectionMap::iterator iter = sections_.find(section);
if (iter == sections_.end()) {
sections_[section] = new ItemMap;
sections_[section] = ItemMap();
iter = sections_.find(section);
}
......@@ -133,9 +119,8 @@ ConfigTree::addConfigTreeItem(const std::string& section, const ConfigTreeItem i
if (iter != sections_.end()) {
std::string name(item.getName());
if (iter->second->find(name) == iter->second->end()) {
(*(iter->second))[name] = item;
}
if (iter->second.find(name) == iter->second.end())
iter->second[name] = item;
}
}
......@@ -163,17 +148,11 @@ ConfigTree::getConfigTreeItemIntValue(const std::string& section, const std::str
bool
ConfigTree::getConfigTreeItemBoolValue(const std::string& section, const std::string& itemName) const
{
std::string configItem = getConfigTreeItemValue(section, itemName);
if (configItem == "true") {
return true;
}
return false;
return getConfigTreeItemValue(section, itemName) == "true";
}
bool
ConfigTree::getConfigTreeItemToken(const std::string& section, const std::string& itemName, TokenList& arg) const
ConfigTree::getConfigTreeItemToken(const std::string& section, const std::string& itemName, std::list<std::string>& arg) const
{
const ConfigTreeItem *item = getConfigTreeItem(section, itemName);
......@@ -186,8 +165,8 @@ ConfigTree::getConfigTreeItemToken(const std::string& section, const std::string
arg.push_back(item->getDefaultValue());
return true;
}
return false;
else
return false;
}
/**
......@@ -201,9 +180,9 @@ ConfigTree::getConfigTreeItem(const std::string& section, const std::string& ite
if (iter == sections_.end())
return NULL;
ItemMap::const_iterator iterItem = iter->second->find(itemName);
ItemMap::const_iterator iterItem = iter->second.find(itemName);
if (iterItem == iter->second->end())
if (iterItem == iter->second.end())
return NULL;
return & (iterItem->second);
......@@ -220,18 +199,17 @@ ConfigTree::setConfigTreeItem(const std::string& section,
const std::string& itemName,
const std::string& value)
{
SectionMap::iterator iter = sections_.find(section);
if (iter == sections_.end()) {
// Not found, create section
sections_[section] = new ItemMap;
sections_[section] = ItemMap();
iter = sections_.find(section);
}
ItemMap::iterator iterItem = iter->second->find(itemName);
ItemMap::iterator iterItem = iter->second.find(itemName);
if (iterItem == iter->second->end()) {
if (iterItem == iter->second.end()) {
// If not found, search in our default list to find
// something that would fit.
std::string defaultValue = getDefaultValue(itemName);
......@@ -240,13 +218,12 @@ ConfigTree::setConfigTreeItem(const std::string& section,
}
// Use default value if the value is empty.
if (value.empty() == true) {
if (value.empty()) {
iterItem->second.setValue(getDefaultValue(itemName));
return true;
}
iterItem->second.setValue(value);
return true;
}
......@@ -254,7 +231,7 @@ ConfigTree::setConfigTreeItem(const std::string& section,
// return false if empty, no config, or enable to open
// return true if everything is ok
bool
ConfigTree::saveConfigTree(const std::string& fileName)
ConfigTree::saveConfigTree(const std::string& fileName) const
{
DEBUG("ConfigTree: Save %s", fileName.c_str());
......@@ -271,20 +248,12 @@ ConfigTree::saveConfigTree(const std::string& fileName)
}
// for each section, for each item...
SectionMap::iterator iter = sections_.begin();
while (iter != sections_.end()) {
for (SectionMap::const_iterator iter = sections_.begin(); iter != sections_.end(); ++iter) {
file << "[" << iter->first << "]" << std::endl;
ItemMap::iterator iterItem = iter->second->begin();
while (iterItem != iter->second->end()) {
for (ItemMap::const_iterator iterItem = iter->second.begin(); iterItem != iter->second.end(); ++iterItem)
file << iterItem->first << "=" << iterItem->second.getValue() << std::endl;
iterItem++;
}
file << std::endl;
iter++;
}
file.close();
......@@ -335,10 +304,9 @@ ConfigTree::populateFromFile(const std::string& fileName)
}
std::string line;
std::string section("");
std::string key("");
std::string val("");
std::string section;
std::string key;
std::string val;
std::string::size_type pos;
while (!file.eof()) {
......@@ -371,16 +339,16 @@ ConfigTree::populateFromFile(const std::string& fileName)
return 1;
}
TokenList
ConfigTreeIterator::begin()
std::list<std::string>
ConfigTreeIterator::begin() const
{
TokenList tk;
std::list<std::string> tk;
iter_ = tree_->sections_.begin();
if (iter_!=tree_->sections_.end()) {
iterItem_ = iter_->second->begin();
if (iter_ != tree_->sections_.end()) {
iterItem_ = iter_->second.begin();
if (iterItem_!=iter_->second->end()) {
if (iterItem_ != iter_->second.end()) {
tk.push_back(iter_->first);
tk.push_back(iterItem_->first);
tk.push_back(iterItem_->second.getType());
......@@ -392,26 +360,26 @@ ConfigTreeIterator::begin()
return tk;
}
TokenList
std::list<std::string>
ConfigTreeIterator::next()
{
TokenList tk;
std::list<std::string> tk;
// we return tk empty if we are at the end of the list...
if (iter_ == tree_->sections_.end())
return tk;
if (iterItem_ != iter_->second->end())
if (iterItem_ != iter_->second.end())
iterItem_++;
if (iterItem_ == iter_->second->end()) {
if (iterItem_ == iter_->second.end()) {
// if we increment, and we are at the end of a section
iter_++;
if (iter_ != tree_->sections_.end()) {
iterItem_ = iter_->second->begin();
iterItem_ = iter_->second.begin();
if (iterItem_ != iter_->second->end()) {
if (iterItem_ != iter_->second.end()) {
tk.push_back(iter_->first);
tk.push_back(iterItem_->first);
tk.push_back(iterItem_->second.getType());
......
......@@ -47,8 +47,7 @@ static const char * const TRUE_STR = "true";
class ConfigTreeItem;
typedef std::map<std::string, ConfigTreeItem> ItemMap;
typedef std::map<std::string, ItemMap*> SectionMap;
typedef std::list<std::string> TokenList;
typedef std::map<std::string, ItemMap> SectionMap;
class ConfigTreeItemException {
};
......@@ -58,25 +57,13 @@ class ConfigTree;
class ConfigTreeIterator {
public:
/**
* Parsing method
* @return TokenList
*/
TokenList begin();
std::list<std::string> begin() const;
/**
* Parsing method
* @return TokenList
*/
const TokenList& end() const {
const std::list<std::string> & end() const {
return endToken_;
}
/**
* Parsing method
* @return TokenList
*/
TokenList next();
std::list<std::string> next();
private:
friend class ConfigTree;
......@@ -85,9 +72,9 @@ class ConfigTreeIterator {
NON_COPYABLE(ConfigTreeIterator);
ConfigTree* tree_;
TokenList endToken_;
SectionMap::iterator iter_;
ItemMap::iterator iterItem_;
std::list<std::string> endToken_;
mutable SectionMap::iterator iter_;
mutable ItemMap::iterator iterItem_;
};
class ConfigTree {
......@@ -118,7 +105,7 @@ class ConfigTree {
*
* @return array Strings of the sections
*/
TokenList getSections();
std::list<std::string> getSections();
void addConfigTreeItem(const std::string& section, const ConfigTreeItem item);
/**
......@@ -149,14 +136,14 @@ class ConfigTree {
/**
* Flush data to .ini file
*/
bool saveConfigTree(const std::string& fileName);
bool saveConfigTree(const std::string& fileName) const;
/**
* Load data (and fill ConfigTree) from disk
*/
int populateFromFile(const std::string& fileName);
bool getConfigTreeItemToken(const std::string& section, const std::string& itemName, TokenList& arg) const;
bool getConfigTreeItemToken(const std::string& section, const std::string& itemName, std::list<std::string>& arg) const;
private:
std::string getDefaultValue(const std::string& key) const;
......@@ -196,19 +183,19 @@ class ConfigTreeItem {
value_ = value;
}
const std::string getName() const {
std::string getName() const {
return name_;
}
const std::string getValue() const {
std::string getValue() const {
return value_;
}
const std::string getDefaultValue() const {
std::string getDefaultValue() const {
return defaultValue_;
}
const std::string getType() const {
std::string getType() const {
return type_;
}
......
......@@ -601,20 +601,10 @@
</arg>
</method>
<method name="getHistory" tp:name-for-bindings="getHistory">
<tp:docstring>
</tp:docstring>
<annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="MapStringString"/>
<arg type="as" name="entries" direction="out">
<tp:docstring>
</tp:docstring>
</arg>
</method>
<method name="getHistorySimple" tp:name-for-bindings="getHistorySimple">
<annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="MapIntMapStringString"/>
<!-- Return a Dict of type <int, Dict<string, string> >...a Dict of Dicts -->
<arg type="a{ia{ss}}" name="info" direction="out"/>
<method name="getHistory" tp:name-for-bindings="getHistory">
<annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorMapStringString"/>
<!-- Return a List of type Dict<string, string> >...a List of Dicts -->
<arg type="aa{ss}" name="entries" direction="out"/>
</method>
<method name="setHistory" tp:name-for-bindings="setHistory">
......
......@@ -398,12 +398,7 @@ void ConfigurationManager::setAccountsOrder(const std::string& order)
Manager::instance().setAccountsOrder(order);
}
std::vector<std::string> ConfigurationManager::getHistory()
{
return Manager::instance().getHistorySerialized();
}
std::map<int, std::map<std::string, std::string> > ConfigurationManager::getHistorySimple()
std::vector<std::map<std::string, std::string> > ConfigurationManager::getHistory()
{
return Manager::instance().getHistory();
}
......
......@@ -123,8 +123,7 @@ class ConfigurationManager :
std::map<std::string, std::string> getHookSettings();
void setHookSettings(const std::map<std::string, std::string>& settings);
std::vector<std::string> getHistory();
std::map<int, std::map<std::string, std::string> > getHistorySimple();
std::vector<std::map<std::string, std::string> > getHistory();
void setHistory(const std::vector<std::string> &entries);
std::map<std::string, std::string> getTlsSettings();
......
......@@ -35,13 +35,15 @@
#include <cstdlib>
#include "manager.h"
static const char * const ITEM_SEPARATOR = "|";
namespace {
const char * const ITEM_SEPARATOR = "|";
}
const char * const HistoryItem::ACCOUNT_ID_KEY = "accountid";
const char * const HistoryItem::CALLID_KEY = "callid";
const char * const HistoryItem::CONFID_KEY = "confid";
const char * const HistoryItem::NAME_KEY = "name";
const char * const HistoryItem::NUMBER_KEY = "number";
const char * const HistoryItem::PEER_NAME_KEY = "peer_name";
const char * const HistoryItem::PEER_NUMBER_KEY = "peer_number";
const char * const HistoryItem::RECORDING_PATH_KEY = "recordfile";
const char * const HistoryItem::TIME_ADDED_KEY = "timeadded";
const char * const HistoryItem::TIMESTAMP_START_KEY = "timestamp_start";
......@@ -58,8 +60,8 @@ HistoryItem::HistoryItem(const std::string &timestampStart,
: accountID_(accountID),
confID_(confID),
callID_(callID),
name_(name),
number_(number),
peerName_(name),
peerNumber_(number),
recordingPath_(recording),
timeAdded_(timeAdded),
timestampStart_(timestampStart),
......@@ -69,7 +71,7 @@ HistoryItem::HistoryItem(const std::string &timestampStart,
HistoryItem::HistoryItem(std::string serialized_form) :
accountID_(), confID_(), callID_(), name_(), number_(), recordingPath_(),
accountID_(), confID_(), callID_(), peerName_(), peerNumber_(), recordingPath_(),
timeAdded_(), timestampStart_(), timestampStop_(),
state_(MISSED)
{
......@@ -83,13 +85,12 @@ HistoryItem::HistoryItem(std::string serialized_form) :
state_ = (HistoryState) atoi(tmp.c_str());
break;
case 1: // The number field
number_ = tmp;
peerNumber_ = tmp;
break;
case 2: // The name field
name_ = tmp;
if (name_ == "empty")
name_ = "";
peerName_ = tmp;
if (peerName_ == "empty")
peerName_ = "";
break;
case 3: // The start timestamp
timestampStart_ = tmp;
......@@ -119,7 +120,7 @@ HistoryItem::HistoryItem(std::string serialized_form) :
}
}
bool HistoryItem::save(Conf::ConfigTree **history)
bool HistoryItem::save(Conf::ConfigTree &history) const
{
std::stringstream section;
std::stringstream state;
......@@ -129,25 +130,25 @@ bool HistoryItem::save(Conf::ConfigTree **history)
std::string sectionstr = section.str();
state << state_;
return (*history)->setConfigTreeItem(sectionstr, STATE_KEY, state.str())
&& (*history)->setConfigTreeItem(sectionstr, TIMESTAMP_START_KEY, timestampStart_)
&& (*history)->setConfigTreeItem(sectionstr, TIMESTAMP_STOP_KEY, timestampStop_)
&& (*history)->setConfigTreeItem(sectionstr, NUMBER_KEY, number_)
&& (*history)->setConfigTreeItem(sectionstr, CALLID_KEY, callID_)
&& (*history)->setConfigTreeItem(sectionstr, ACCOUNT_ID_KEY, accountID_)
&& (*history)->setConfigTreeItem(sectionstr, NAME_KEY, name_)
&& (*history)->setConfigTreeItem(sectionstr, RECORDING_PATH_KEY, recordingPath_)
&& (*history)->setConfigTreeItem(sectionstr, CONFID_KEY, confID_)
&& (*history)->setConfigTreeItem(sectionstr, TIME_ADDED_KEY, timeAdded_);
return history.setConfigTreeItem(sectionstr, STATE_KEY, state.str())
and history.setConfigTreeItem(sectionstr, TIMESTAMP_START_KEY, timestampStart_)
and history.setConfigTreeItem(sectionstr, TIMESTAMP_STOP_KEY, timestampStop_)
and history.setConfigTreeItem(sectionstr, PEER_NUMBER_KEY, peerNumber_)
and history.setConfigTreeItem(sectionstr, CALLID_KEY, callID_)
and history.setConfigTreeItem(sectionstr, ACCOUNT_ID_KEY, accountID_)
and history.setConfigTreeItem(sectionstr, PEER_NAME_KEY, peerName_)
and history.setConfigTreeItem(sectionstr, RECORDING_PATH_KEY, recordingPath_)
and history.setConfigTreeItem(sectionstr, CONFID_KEY, confID_)
and history.setConfigTreeItem(sectionstr, TIME_ADDED_KEY, timeAdded_);
}
std::string HistoryItem::serialize() const
{
// Replace empty string with a valid standard string value
std::string name(name_);
std::string peerName(peerName_);
if (name.empty())
name = "empty";
if (peerName.empty())
peerName = "empty";
// For the account ID, check also if the accountID corresponds to an existing account
// ie the account may have been removed
......@@ -158,7 +159,7 @@ std::string HistoryItem::serialize() const
std::stringstream res;
// Serialize it
res << state_ << ITEM_SEPARATOR << number_ << ITEM_SEPARATOR << name << ITEM_SEPARATOR << timestampStart_ << ITEM_SEPARATOR << timestampStop_
res << state_ << ITEM_SEPARATOR << peerNumber_ << ITEM_SEPARATOR << peerName << ITEM_SEPARATOR << timestampStart_ << ITEM_SEPARATOR << timestampStop_
<< ITEM_SEPARATOR << callID_ << ITEM_SEPARATOR << accountID << ITEM_SEPARATOR << recordingPath_ << ITEM_SEPARATOR << confID_ << ITEM_SEPARATOR << timeAdded_;
return res.str();
......@@ -169,10 +170,10 @@ std::map<std::string, std::string> HistoryItem::toMap() const
std::map<std::string, std::string> result;
// Replace empty string with a valid standard string value
if (name_.empty())
result[NAME_KEY] = "empty";
if (peerName_.empty())
result[PEER_NAME_KEY] = "empty";
else
result[NAME_KEY] = name_;
result[PEER_NAME_KEY] = peerName_;
// For the account ID, check also if the accountID corresponds to an existing account
// ie the account may have been removed
......@@ -184,7 +185,7 @@ std::map<std::string, std::string> HistoryItem::toMap() const
result[ACCOUNT_ID_KEY] = accountID_;
result[STATE_KEY] = state_;
result[NUMBER_KEY] = number_;
result[PEER_NUMBER_KEY] = peerNumber_;
result[TIMESTAMP_START_KEY] = timestampStart_;
result[TIMESTAMP_STOP_KEY] = timestampStop_;
result[CALLID_KEY] = callID_;
......@@ -200,3 +201,8 @@ bool HistoryItem::valid_account(const std::string &id) const
{
return Manager::instance().accountExists(id);
}
bool HistoryItem::youngerThan(int otherTime) const
{
return atoi(timestampStart_.c_str()) >= otherTime;
}
......@@ -51,8 +51,8 @@ class HistoryItem {
static const char * const ACCOUNT_ID_KEY;
static const char * const CONFID_KEY;
static const char * const CALLID_KEY;
static const char * const NAME_KEY;
static const char * const NUMBER_KEY;
static const char * const PEER_NAME_KEY;
static const char * const PEER_NUMBER_KEY;
static const char * const RECORDING_PATH_KEY;
static const char * const TIME_ADDED_KEY;
static const char * const TIMESTAMP_START_KEY;
......@@ -87,7 +87,9 @@ class HistoryItem {
return timestampStart_;
}
bool save(Conf::ConfigTree **history);
bool youngerThan(int otherTime) const;
bool save(Conf::ConfigTree &history) const;
std::string serialize() const;
std::map<std::string, std::string> toMap() const;
......@@ -116,8 +118,8 @@ class HistoryItem {
/*
* The information about the callee/caller, depending on the type of call.
*/
std::string name_;
std::string number_;
std::string peerName_;
std::string peerNumber_;
/**
* Path of recording for this call, if it exists
......
......@@ -37,70 +37,79 @@
#include "config/config.h"
namespace {
int get_unix_timestamp_equivalent(int days) {
int get_unix_timestamp_equivalent(int days)
{
// Number of seconds in one day: 60 x 60 x 24
static const int DAY_UNIX_TIMESTAMP = 86400;
return days * DAY_UNIX_TIMESTAMP;
}
int getConfigInt(const std::string& section, const std::string& name, const Conf::ConfigTree &historyList)
{
return historyList.getConfigTreeItemIntValue(section, name);
}
std::string getConfigString(const std::string& section, const std::string& name, const Conf::ConfigTree &historyList)
{
return historyList.getConfigTreeItemValue(section, name);
}
}
HistoryManager::HistoryManager() :
history_items_(), history_items_simple_(), history_loaded_(false), history_path_("")
history_items_(), history_loaded_(false), history_path_("")
{}
int HistoryManager::load_history(int limit, const std::string &path)
int HistoryManager::loadHistory(int limit, const std::string &path)
{
Conf::ConfigTree history_list;