diff options
author | Kamil Rytarowski <kamil@mageia.org> | 2012-12-25 14:18:23 +0000 |
---|---|---|
committer | Kamil Rytarowski <kamil@mageia.org> | 2012-12-25 14:18:23 +0000 |
commit | 2437820b0fd29fde81e4bd919adff80a1c87ead8 (patch) | |
tree | 05bb595b8b0af9ad1680d2dd3ecd781b2b36d07d /main.cpp | |
download | mgasvnstats-2437820b0fd29fde81e4bd919adff80a1c87ead8.tar mgasvnstats-2437820b0fd29fde81e4bd919adff80a1c87ead8.tar.gz mgasvnstats-2437820b0fd29fde81e4bd919adff80a1c87ead8.tar.bz2 mgasvnstats-2437820b0fd29fde81e4bd919adff80a1c87ead8.tar.xz mgasvnstats-2437820b0fd29fde81e4bd919adff80a1c87ead8.zip |
Initial import.
Diffstat (limited to 'main.cpp')
-rw-r--r-- | main.cpp | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..2e44f8b --- /dev/null +++ b/main.cpp @@ -0,0 +1,167 @@ +/* +** Copyright 2012 Kamil Rytarowski < kamil AT mageia DOT org > +** +** This Source Code Form is subject to the terms of the Mozilla Public +** License, v. 2.0. If a copy of the MPL was not distributed with this +** file, You can obtain one at http://mozilla.org/MPL/2.0/. +*/ + +#include <chrono> +#include <cstdlib> +#include <ctime> +#include <iomanip> +#include <iostream> +#include <locale> +#include <map> +#include <set> +#include <sstream> +#include <string> +#include <tuple> +#include <vector> + +#include <boost/date_time/posix_time/posix_time.hpp> + +#include "pugixml.hpp" + +typedef std::tuple<unsigned long /* revision */, + std::string /* author */, + boost::posix_time::ptime /* date */> tuple; + +int main(int argc, char **argv) +{ + /* + ** Read text stream from stdin + */ + + std::cin >> std::noskipws; /* Don't skip whitespaces */ + + /* + ** Use iterators to slurp data from the standard input + */ + + std::istream_iterator<char> it(std::cin); + std::istream_iterator<char> end; + const std::string input(it, end); + + pugi::xml_document doc; + pugi::xml_parse_result result = doc.load_buffer(input.c_str(), input.size()); + +#ifndef NDEBUG + std::cerr << "Load result: " << result.description() << "\n"; +#endif + + /* + ** <?xml version="1.0" encoding="UTF-8"?> + ** <log> + ** <logentry + ** revision="1234"> + ** <author>author</author> + ** <date>2012-01-21T10:00:00.000000Z</date> + ** </logentry> + ** </log> + */ + pugi::xml_node log = doc.child("log"); + + std::vector<tuple> table; + + for (pugi::xml_node logentry: log.children()) + { + unsigned long revision = std::stoul(logentry.attribute("revision").value()); + std::string author = logentry.child("author").text().get(); + +#ifndef NDEBUG + std::cerr << revision << "\t" << author << "\t"; +#endif + + std::string datetime = logentry.child("date").text().get(); + boost::posix_time::time_input_facet * facet = + new boost::posix_time::time_input_facet("%Y-%m-%dT%H:%M:%sZ"); /* 'Z' stands for UTC */ + + std::stringstream ss; + ss.imbue(std::locale(std::locale(), facet)); + ss << datetime; + boost::posix_time::ptime date; + ss >> date; + +#ifndef NDEBUG + std::cerr << datetime << "\t" << date << "\n"; +#endif + + table.push_back(std::make_tuple(revision, author, date)); + } + + /* + ** Statistics: + ** + ** 1. Overall number of the commiters + ** 2. Number of commits per a commiter + ** 3. + */ + + /* + ** 1. Overall number of the commiters + */ + + unsigned int overall_commiters = 0; + { + std::set<std::string> tmp_set; + overall_commiters = + (unsigned int) count_if(table.begin(), table.end(), [&tmp_set](tuple & t) + { + std::string author = std::get<1>(t); + + if (tmp_set.empty()) + { + tmp_set.insert(author); + return true; + } + else + { + if (tmp_set.find(author) == tmp_set.end()) + { + tmp_set.insert(author); + return true; + } + else + return false; + } + } + ); + } + +#ifndef NDEBUG + std::cerr << "Overall commiters: " << overall_commiters << "\n"; +#endif + + /* + ** 2. Number of commits per a commiter + */ + + std::map<std::string, unsigned int> commits_per_a_commiter; + { + for(auto t : table) + { + std::string author = std::get<1>(t); + if (commits_per_a_commiter.empty()) + commits_per_a_commiter.insert(std::pair<std::string, unsigned int>(author, 1)); + else + { + auto a = commits_per_a_commiter.find(author); + if (a == commits_per_a_commiter.end()) + commits_per_a_commiter.insert(std::pair<std::string, unsigned int>(author, 1)); + else + commits_per_a_commiter.at(author) = (commits_per_a_commiter.at(author) + 1); + } + } + } + +#ifndef NDEBUG + std::cerr << "Commits per a commiter:\n"; + for(auto c : commits_per_a_commiter) + { + std::cerr << "\t" << (c.first) << "\t" << (c.second) << "\n"; + } +#endif + + return EXIT_SUCCESS; +} |