From: Arvin Schnell Date: Mon, 21 May 2012 15:56:20 +0000 (+0200) Subject: - work on dbus interface X-Git-Tag: v0.1.3~229 X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=9701e86c8a4e92a939506bdbee4625e435aad7b3;p=thirdparty%2Fsnapper.git - work on dbus interface --- diff --git a/client/Makefile.am b/client/Makefile.am index 1ea75e60..adcf025b 100644 --- a/client/Makefile.am +++ b/client/Makefile.am @@ -12,7 +12,8 @@ bin_PROGRAMS = snapper snapper_SOURCES = \ snapper.cc \ types.cc types.h \ - commands.cc commands.h + commands.cc commands.h \ + cleanup.cc cleanup.h snapper_LDADD = ../snapper/libsnapper.la utils/libutils.la ../dbus/libdbus.la -ldbus-1 diff --git a/client/cleanup.cc b/client/cleanup.cc new file mode 100644 index 00000000..782e58b4 --- /dev/null +++ b/client/cleanup.cc @@ -0,0 +1,339 @@ +/* + * Copyright (c) [2011-2012] Novell, Inc. + * + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as published + * by the Free Software Foundation. + * + * 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, contact Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, you may + * find current contact information at www.novell.com. + */ + + +#include + +#include "commands.h" + + +using namespace std; + + +struct younger_than +{ + younger_than(time_t t) + : t(t) {} + bool operator()(XSnapshots::const_iterator it) + { return it->getDate() > t; } + const time_t t; +}; + + +// Removes snapshots younger than min_age from tmp +void +filter1(list& tmp, time_t min_age) +{ + tmp.remove_if(younger_than(time(NULL) - min_age)); +} + + +// Removes pre and post snapshots from tmp that do have a corresponding +// snapshot but which is not included in tmp. +void +filter2(const XSnapshots& snapshots, list& tmp) +{ + list ret; + + for (list::const_iterator it1 = tmp.begin(); it1 != tmp.end(); ++it1) + { + if ((*it1)->getType() == XPRE) + { + XSnapshots::const_iterator it2 = snapshots.findPost(*it1); + if (it2 != snapshots.end()) + { + if (find(tmp.begin(), tmp.end(), it2) == tmp.end()) + continue; + } + } + + if ((*it1)->getType() == XPOST) + { + XSnapshots::const_iterator it2 = snapshots.findPre(*it1); + if (it2 != snapshots.end()) + { + if (find(tmp.begin(), tmp.end(), it2) == tmp.end()) + continue; + } + } + + ret.push_back(*it1); + } + + swap(ret, tmp); +} + + +bool +do_cleanup_number(DBus::Connection& conn, const string& config_name) +{ + time_t min_age = 1800; + size_t limit = 50; + + /* + TODO + string val; + if (config->getValue("NUMBER_MIN_AGE", val)) + val >> min_age; + if (config->getValue("NUMBER_LIMIT", val)) + val >> limit; + */ + + XSnapshots snapshots = command_list_xsnapshots(conn, config_name); + + list tmp; + + for (XSnapshots::const_iterator it = snapshots.begin(); it != snapshots.end(); ++it) + { + if (it->getCleanup() == "number") + tmp.push_back(it); + } + + if (tmp.size() > limit) + { + list::iterator it = tmp.end(); + advance(it, - limit); + tmp.erase(it, tmp.end()); + + filter1(tmp, min_age); + filter2(snapshots, tmp); + + for (list::const_iterator it = tmp.begin(); it != tmp.end(); ++it) + command_delete_xsnapshot(conn, config_name, (*it)->getNum()); + } + + return true; +} + + +bool +is_first(list::const_iterator first, + list::const_iterator last, + XSnapshots::const_iterator it1, + std::function pred) +{ + time_t t1 = it1->getDate(); + struct tm tmp1; + localtime_r(&t1, &tmp1); + + for (list::const_iterator it2 = first; it2 != last; ++it2) + { + if (it1 == *it2) + continue; + + time_t t2 = (*it2)->getDate(); + struct tm tmp2; + localtime_r(&t2, &tmp2); + + if (!pred(tmp1, tmp2)) + return true; + + if (t1 > t2) + return false; + } + + return true; +} + + +bool +equal_year(const struct tm& tmp1, const struct tm& tmp2) +{ + return tmp1.tm_year == tmp2.tm_year; +} + +bool +equal_month(const struct tm& tmp1, const struct tm& tmp2) +{ + return equal_year(tmp1, tmp2) && tmp1.tm_mon == tmp2.tm_mon; +} + +bool +equal_day(const struct tm& tmp1, const struct tm& tmp2) +{ + return equal_month(tmp1, tmp2) && tmp1.tm_mday == tmp2.tm_mday; +} + +bool +equal_hour(const struct tm& tmp1, const struct tm& tmp2) +{ + return equal_day(tmp1, tmp2) && tmp1.tm_hour == tmp2.tm_hour; +} + + +bool +is_first_yearly(list::const_iterator first, + list::const_iterator last, + XSnapshots::const_iterator it1) +{ + return is_first(first, last, it1, equal_year); +} + +bool +is_first_monthly(list::const_iterator first, + list::const_iterator last, + XSnapshots::const_iterator it1) +{ + return is_first(first, last, it1, equal_month); +} + +bool +is_first_daily(list::const_iterator first, + list::const_iterator last, + XSnapshots::const_iterator it1) +{ + return is_first(first, last, it1, equal_day); +} + +bool +is_first_hourly(list::const_iterator first, + list::const_iterator last, + XSnapshots::const_iterator it1) +{ + return is_first(first, last, it1, equal_hour); +} + + +bool +do_cleanup_timeline(DBus::Connection& conn, const string& config_name) +{ + time_t min_age = 1800; + size_t limit_hourly = 10; + size_t limit_daily = 10; + size_t limit_monthly = 10; + size_t limit_yearly = 10; + + /* + TODO + string val; + if (config->getValue("TIMELINE_MIN_AGE", val)) + val >> min_age; + if (config->getValue("TIMELINE_LIMIT_HOURLY", val)) + val >> limit_hourly; + if (config->getValue("TIMELINE_LIMIT_DAILY", val)) + val >> limit_daily; + if (config->getValue("TIMELINE_LIMIT_MONTHLY", val)) + val >> limit_monthly; + if (config->getValue("TIMELINE_LIMIT_YEARLY", val)) + val >> limit_yearly; + */ + + size_t num_hourly = 0; + size_t num_daily = 0; + size_t num_monthly = 0; + size_t num_yearly = 0; + + XSnapshots snapshots = command_list_xsnapshots(conn, config_name); + + list tmp; + + for (XSnapshots::const_iterator it = snapshots.begin(); it != snapshots.end(); ++it) + { + if (it->getCleanup() == "timeline") + tmp.push_front(it); + } + + list::iterator it = tmp.begin(); + while (it != tmp.end()) + { + if (num_hourly < limit_hourly && is_first_hourly(it, tmp.end(), *it)) + { + ++num_hourly; + it = tmp.erase(it); + } + else if (num_daily < limit_daily && is_first_daily(it, tmp.end(), *it)) + { + ++num_daily; + it = tmp.erase(it); + } + else if (num_monthly < limit_monthly && is_first_monthly(it, tmp.end(), *it)) + { + ++num_monthly; + it = tmp.erase(it); + } + else if (num_yearly < limit_yearly && is_first_yearly(it, tmp.end(), *it)) + { + ++num_yearly; + it = tmp.erase(it); + } + else + { + ++it; + } + } + + tmp.reverse(); + + filter1(tmp, min_age); + filter2(snapshots, tmp); + + for (list::const_iterator it = tmp.begin(); it != tmp.end(); ++it) + command_delete_xsnapshot(conn, config_name, (*it)->getNum()); + + return true; +} + + +bool +do_cleanup_empty_pre_post(DBus::Connection& conn, const string& config_name) +{ + time_t min_age = 1800; + + /* + TODO + string val; + if (config->getValue("EMPTY_PRE_POST_MIN_AGE", val)) + val >> min_age; + */ + + XSnapshots snapshots = command_list_xsnapshots(conn, config_name); + + list tmp; + + for (XSnapshots::const_iterator it1 = snapshots.begin(); it1 != snapshots.end(); ++it1) + { + if (it1->getType() == XPRE) + { + XSnapshots::const_iterator it2 = snapshots.findPost(it1); + + if (it2 != snapshots.end()) + { + command_create_xcomparison(conn, config_name, it1->getNum(), it2->getNum()); + + list files = command_get_xfiles(conn, config_name, it1->getNum(), it2->getNum()); + + if (files.empty()) + { + tmp.push_back(it1); + tmp.push_back(it2); + } + } + } + } + + filter1(tmp, min_age); + filter2(snapshots, tmp); + + for (list::const_iterator it = tmp.begin(); it != tmp.end(); ++it) + command_delete_xsnapshot(conn, config_name, (*it)->getNum()); + + return true; +} diff --git a/client/cleanup.h b/client/cleanup.h new file mode 100644 index 00000000..0c5e3f09 --- /dev/null +++ b/client/cleanup.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) [2011-2012] Novell, Inc. + * + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as published + * by the Free Software Foundation. + * + * 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, contact Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, you may + * find current contact information at www.novell.com. + */ + + +bool +do_cleanup_number(DBus::Connection& conn, const string& config_name); + +bool +do_cleanup_timeline(DBus::Connection& conn, const string& config_name); + +bool +do_cleanup_empty_pre_post(DBus::Connection& conn, const string& config_name); diff --git a/client/commands.cc b/client/commands.cc index a529a23c..9a7fae97 100644 --- a/client/commands.cc +++ b/client/commands.cc @@ -285,16 +285,3 @@ command_get_xundostatistic(DBus::Connection& conn, const string& config_name, un return ret; } - - -void -command_xcleanup(DBus::Connection& conn, const string& config_name, const string& algorithm) - -{ - DBus::MessageMethodCall call(SERVICE, OBJECT, INTERFACE, "Cleanup"); - - DBus::Hoho hoho(call); - hoho << config_name << algorithm; - - DBus::Message reply = conn.send_and_reply_and_block(call); -} diff --git a/client/commands.h b/client/commands.h index 0f6a7b1e..fa6889f8 100644 --- a/client/commands.h +++ b/client/commands.h @@ -94,6 +94,3 @@ command_set_xundo_all(DBus::Connection& conn, const string& config_name, unsigne XUndoStatistic command_get_xundostatistic(DBus::Connection& conn, const string& config_name, unsigned int number1, unsigned int number2); - -void -command_xcleanup(DBus::Connection& conn, const string& config_name, const string& algorithm); diff --git a/client/snapper.cc b/client/snapper.cc index 6a456783..50af7a71 100644 --- a/client/snapper.cc +++ b/client/snapper.cc @@ -37,6 +37,7 @@ #include "utils/GetOpts.h" #include "commands.h" +#include "cleanup.h" using namespace snapper; using namespace std; @@ -50,7 +51,6 @@ GetOpts getopts; bool quiet = false; bool verbose = false; string config_name = "root"; -bool disable_filters = false; unsigned int @@ -1031,9 +1031,17 @@ command_cleanup(DBus::Connection& conn) string cleanup = getopts.popArg(); - if (cleanup == "number" || cleanup == "timeline" || cleanup == "empty-pre-post") + if (cleanup == "number") { - command_xcleanup(conn, config_name, cleanup); + do_cleanup_number(conn, config_name); + } + else if (cleanup == "timeline") + { + do_cleanup_timeline(conn, config_name); + } + else if (cleanup == "empty-pre-post") + { + do_cleanup_empty_pre_post(conn, config_name); } else { @@ -1061,7 +1069,6 @@ help() << _("\t--verbose, -v\t\t\tIncrease verbosity.") << endl << _("\t--table-style, -t