From 5543044bd35496ebe042ad5cf98f4353b657bf2d Mon Sep 17 00:00:00 2001 From: Eric Frias Date: Mon, 31 Mar 2014 16:10:52 -0400 Subject: [PATCH] Collect time of git commit for display in Keyhotee, add function for pretty-printing times --- CMakeLists.txt | 1 + GitSHA3.cpp.in | 3 + GitSHA3.h | 1 + GitVersionGen/GetGitRevisionDescription.cmake | 46 ++++++++++++++ include/fc/time.hpp | 6 ++ src/time.cpp | 60 +++++++++++++++++++ 6 files changed, 117 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index c44aab812..1e9285188 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,6 +16,7 @@ INCLUDE( SetupTargetMacros ) INCLUDE(GetGitRevisionDescription) get_git_head_revision(GIT_REFSPEC GIT_SHA3) +get_git_unix_timestamp(GIT_UNIX_TIMESTAMP3) SET( DEFAULT_HEADER_INSTALL_DIR include/\${target} ) SET( DEFAULT_LIBRARY_INSTALL_DIR lib/ ) diff --git a/GitSHA3.cpp.in b/GitSHA3.cpp.in index 2e3e8eb98..045015ebc 100644 --- a/GitSHA3.cpp.in +++ b/GitSHA3.cpp.in @@ -1,4 +1,7 @@ +#include #include "GitSHA3.h" #define GIT_SHA3 "@GIT_SHA3@" const char* const g_GIT_SHA3 = GIT_SHA3; +#define GIT_UNIX_TIMESTAMP3 @GIT_UNIX_TIMESTAMP3@ +const uint32_t g_GIT_UNIX_TIMESTAMP3 = GIT_UNIX_TIMESTAMP3; diff --git a/GitSHA3.h b/GitSHA3.h index b70e5c7d1..cb8830e52 100644 --- a/GitSHA3.h +++ b/GitSHA3.h @@ -2,6 +2,7 @@ #define __GITSHA3_H extern const char* const g_GIT_SHA3; +extern const uint32_t g_GIT_UNIX_TIMESTAMP3; #define APPLICATION_VERSION "1.0 Beta1" diff --git a/GitVersionGen/GetGitRevisionDescription.cmake b/GitVersionGen/GetGitRevisionDescription.cmake index c8d27f2e8..00f872715 100644 --- a/GitVersionGen/GetGitRevisionDescription.cmake +++ b/GitVersionGen/GetGitRevisionDescription.cmake @@ -124,6 +124,52 @@ function(git_describe _var) set(${_var} "${out}" PARENT_SCOPE) endfunction() +function(get_git_unix_timestamp _var) + if(NOT GIT_FOUND) + find_package(Git QUIET) + endif() + get_git_head_revision(refspec hash) + if(NOT GIT_FOUND) + set(${_var} "GIT-NOTFOUND" PARENT_SCOPE) + return() + endif() + if(NOT hash) + set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE) + return() + endif() + + # TODO sanitize + #if((${ARGN}" MATCHES "&&") OR + # (ARGN MATCHES "||") OR + # (ARGN MATCHES "\\;")) + # message("Please report the following error to the project!") + # message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}") + #endif() + + # message(STATUS "Arguments to execute_process: ${ARGN}") + + execute_process(COMMAND + "${GIT_EXECUTABLE}" + "show" + "-s" + "--format=%ct" + ${hash} + ${ARGN} + WORKING_DIRECTORY + "${CMAKE_CURRENT_SOURCE_DIR}" + RESULT_VARIABLE + res + OUTPUT_VARIABLE + out + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + if(NOT res EQUAL 0) + set(out "${out}-${res}-NOTFOUND") + endif() + + set(${_var} "${out}" PARENT_SCOPE) +endfunction() + function(git_get_exact_tag _var) git_describe(out --exact-match ${ARGN}) set(${_var} "${out}" PARENT_SCOPE) diff --git a/include/fc/time.hpp b/include/fc/time.hpp index 03c06e6b2..9c0eda2e3 100644 --- a/include/fc/time.hpp +++ b/include/fc/time.hpp @@ -98,6 +98,12 @@ namespace fc { }; typedef fc::optional otime_point; + + /** return a human-readable approximate time, relative to now() + * e.g., "4 hours ago", "2 months ago", etc. + */ + string get_approximate_relative_time_string(const time_point_sec& event_time); + string get_approximate_relative_time_string(const time_point& event_time); } #ifdef _MSC_VER diff --git a/src/time.cpp b/src/time.cpp index 88c7b4652..ed3e8ef11 100644 --- a/src/time.cpp +++ b/src/time.cpp @@ -3,6 +3,8 @@ #include #include #include +#include +#include namespace fc { namespace bch = boost::chrono; @@ -33,4 +35,62 @@ namespace fc { void from_variant( const fc::variant& v, fc::time_point_sec& t ) { t = fc::time_point::from_iso_string(v.as_string()); } + + // inspired by show_date_relative() in git's date.c + string get_approximate_relative_time_string(const time_point_sec& event_time) { + time_point_sec now_in_sec(time_point::now()); + if (event_time > now_in_sec) + return "in the future"; + stringstream result; + uint32_t seconds_ago = now_in_sec.sec_since_epoch() - event_time.sec_since_epoch(); + if (seconds_ago < 90) + { + result << seconds_ago << " second" << (seconds_ago > 1 ? "s" : "") << " ago"; + return result.str(); + } + uint32_t minutes_ago = (seconds_ago + 30) / 60; + if (minutes_ago < 90) + { + result << minutes_ago << " minute" << (minutes_ago > 1 ? "s" : "") << " ago"; + return result.str(); + } + uint32_t hours_ago = (minutes_ago + 30) / 60; + if (hours_ago < 90) + { + result << hours_ago << " hour" << (hours_ago > 1 ? "s" : "") << " ago"; + return result.str(); + } + uint32_t days_ago = (hours_ago + 12) / 24; + if (days_ago < 90) + { + result << days_ago << " day" << (days_ago > 1 ? "s" : "") << " ago"; + return result.str(); + } + uint32_t weeks_ago = (days_ago + 3) / 7; + if (weeks_ago < 70) + { + result << weeks_ago << " week" << (weeks_ago > 1 ? "s" : "") << " ago"; + return result.str(); + } + uint32_t months_ago = (days_ago + 15) / 30; + if (months_ago < 12) + { + result << months_ago << " month" << (months_ago > 1 ? "s" : "") << " ago"; + return result.str(); + } + uint32_t years_ago = days_ago / 365; + result << years_ago << " year" << (months_ago > 1 ? "s" : ""); + if (months_ago < 12 * 5) + { + uint32_t leftover_days = days_ago - (years_ago * 365); + uint32_t leftover_months = (leftover_days + 15) / 30; + if (leftover_months) + result << leftover_months << " month" << (months_ago > 1 ? "s" : ""); + } + result << " ago"; + return result.str(); + } + string get_approximate_relative_time_string(const time_point& event_time) { + return get_approximate_relative_time_string(time_point_sec(event_time)); + } }