Fossil SCM
Added view=byuser param to /stats_report.
Commit
08b9b5b0d9e9cf885b140e622ca5816612b69c4f
Parent
0de658266004a94…
1 file changed
+70
-7
+70
-7
| --- src/timeline.c | ||
| +++ src/timeline.c | ||
| @@ -1836,12 +1836,12 @@ | ||
| 1836 | 1836 | ** If includeMonth is true then it generates the "bymonth" report, |
| 1837 | 1837 | ** else the "byyear" report. If zUserName is not NULL and not empty |
| 1838 | 1838 | ** then the report is restricted to events created by the named user |
| 1839 | 1839 | ** account. |
| 1840 | 1840 | */ |
| 1841 | -static void stats_report_bymonthyear(char includeMonth, | |
| 1842 | - char const * zUserName){ | |
| 1841 | +static void stats_report_by_month_year(char includeMonth, | |
| 1842 | + char const * zUserName){ | |
| 1843 | 1843 | Stmt query = empty_Stmt; |
| 1844 | 1844 | int const nPixelsPerEvent = 1; /* for sizing the "graph" part */ |
| 1845 | 1845 | int nRowNumber = 0; /* current TR number */ |
| 1846 | 1846 | int nEventTotal = 0; /* Total event count */ |
| 1847 | 1847 | int rowClass = 0; /* counter for alternating |
| @@ -1941,37 +1941,100 @@ | ||
| 1941 | 1941 | @ <td colspan='3'>Total events: %d(nEventTotal)</td> |
| 1942 | 1942 | @ </tr> |
| 1943 | 1943 | @ </tbody></table> |
| 1944 | 1944 | db_finalize(&query); |
| 1945 | 1945 | } |
| 1946 | + | |
| 1947 | +void stats_report_by_user(){ | |
| 1948 | + Stmt query = empty_Stmt; | |
| 1949 | + int const nPixelsPerEvent = 1; /* for sizing the "graph" part */ | |
| 1950 | + int nRowNumber = 0; /* current TR number */ | |
| 1951 | + int nEventTotal = 0; /* Total event count */ | |
| 1952 | + int rowClass = 0; /* counter for alternating | |
| 1953 | + row colors */ | |
| 1954 | + Blob sql = empty_blob; /* SQL */ | |
| 1955 | + blob_append(&sql, | |
| 1956 | + "SELECT user, " | |
| 1957 | + "COUNT(*) AS eventCount " | |
| 1958 | + "FROM event " | |
| 1959 | + "GROUP BY user ORDER BY user", | |
| 1960 | + -1); | |
| 1961 | + db_prepare(&query, blob_str(&sql)); | |
| 1962 | + blob_reset(&sql); | |
| 1963 | + @ <h1>Timeline Events by User</h1> | |
| 1964 | + @ <table class='statistics-report-table-events' border='0' cellpadding='2' cellspacing='0'> | |
| 1965 | + @ <thead> | |
| 1966 | + @ <th>User</th> | |
| 1967 | + @ <th>Events</th> | |
| 1968 | + @ <th><!-- relative commits graph --></th> | |
| 1969 | + @ </thead><tbody> | |
| 1970 | + while( SQLITE_ROW == db_step(&query) ){ | |
| 1971 | + char const * zUser = db_column_text(&query, 0); | |
| 1972 | + int const nCount = db_column_int(&query, 1); | |
| 1973 | + int const nSize = 1+((nPixelsPerEvent * nCount) / 10); | |
| 1974 | + if(!nCount) continue; | |
| 1975 | + rowClass = ++nRowNumber % 2; | |
| 1976 | + nEventTotal += nCount; | |
| 1977 | + @<tr class='row%d(rowClass)'> | |
| 1978 | + @ <td> | |
| 1979 | + @ <a href="?view=byyear&user=%h(zUser)" target="_new">%s(zUser)</a> | |
| 1980 | + @ </td><td>%d(nCount)</td> | |
| 1981 | + @ <td> | |
| 1982 | + @ <div class='statistics-report-graph-line' style='height:16px; width:%d(nSize)px;'> | |
| 1983 | + @ </div></td> | |
| 1984 | + @</tr> | |
| 1985 | + /* | |
| 1986 | + Potential improvement: calculate the min/max event counts and | |
| 1987 | + use percent-based graph bars. | |
| 1988 | + */ | |
| 1989 | + } | |
| 1990 | + | |
| 1991 | + rowClass = ++nRowNumber % 2; | |
| 1992 | + @ <tr class='row%d(rowClass)'> | |
| 1993 | + @ <td colspan='3'>Total events: %d(nEventTotal)</td> | |
| 1994 | + @ </tr> | |
| 1995 | + @ </tbody></table> | |
| 1996 | + db_finalize(&query); | |
| 1997 | +} | |
| 1946 | 1998 | |
| 1947 | 1999 | /* |
| 1948 | 2000 | ** WEBPAGE: stats_report |
| 1949 | 2001 | ** |
| 1950 | 2002 | ** Shows activity reports for the repository. |
| 1951 | 2003 | ** |
| 1952 | 2004 | ** Query Parameters: |
| 1953 | 2005 | ** |
| 1954 | -** view=REPORT_NAME Valid values: bymonth, byyear | |
| 2006 | +** view=REPORT_NAME Valid values: bymonth, byyear, byuser | |
| 1955 | 2007 | ** user=NAME Restricts statistics to the given user |
| 1956 | 2008 | */ |
| 1957 | 2009 | void stats_report_page(){ |
| 1958 | 2010 | HQuery url; /* URL for various branch links */ |
| 1959 | 2011 | char const * zView = PD("view","bymonth"); /* Which view/report to show. */ |
| 1960 | 2012 | char const *zUserName = P("user"); |
| 2013 | + int whichReport = 0; | |
| 1961 | 2014 | url_initialize(&url, "stats_report"); |
| 2015 | + /* We have to figure out which report to run before continuing so | |
| 2016 | + that we can add (or not) the user= param to the buttons in a sane | |
| 2017 | + manner. | |
| 2018 | + */ | |
| 1962 | 2019 | if(zUserName && *zUserName){ |
| 1963 | 2020 | url_add_parameter(&url,"user", zUserName); |
| 1964 | 2021 | } |
| 1965 | 2022 | timeline_submenu(&url, "By Year", "view", "byyear", 0); |
| 1966 | 2023 | timeline_submenu(&url, "By Month", "view", "bymonth", 0); |
| 2024 | + timeline_submenu(&url, "By User", "view", "byuser", "user"); | |
| 1967 | 2025 | url_reset(&url); |
| 1968 | 2026 | style_header("Activity Reports"); |
| 1969 | - if(0==fossil_strcmp(zView,"bymonth")){ | |
| 1970 | - stats_report_bymonthyear(1, zUserName); | |
| 1971 | - }else if(0==fossil_strcmp(zView,"byyear")){ | |
| 1972 | - stats_report_bymonthyear(0, zUserName); | |
| 2027 | + if(0==fossil_strcmp(zView,"byyear")){ | |
| 2028 | + stats_report_by_month_year(0, zUserName); | |
| 2029 | + }else if(0==fossil_strcmp(zView,"bymonth")){ | |
| 2030 | + stats_report_by_month_year(1, zUserName); | |
| 1973 | 2031 | }else if(0==fossil_strcmp(zView,"byweek")){ |
| 1974 | 2032 | @ TODO: by-week report. |
| 2033 | + }else if(0==fossil_strcmp(zView,"byuser")){ | |
| 2034 | + stats_report_by_user(); | |
| 2035 | + }else{ | |
| 2036 | + @ TODO: show report select list. | |
| 1975 | 2037 | } |
| 2038 | + | |
| 1976 | 2039 | style_footer(); |
| 1977 | 2040 | } |
| 1978 | 2041 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -1836,12 +1836,12 @@ | |
| 1836 | ** If includeMonth is true then it generates the "bymonth" report, |
| 1837 | ** else the "byyear" report. If zUserName is not NULL and not empty |
| 1838 | ** then the report is restricted to events created by the named user |
| 1839 | ** account. |
| 1840 | */ |
| 1841 | static void stats_report_bymonthyear(char includeMonth, |
| 1842 | char const * zUserName){ |
| 1843 | Stmt query = empty_Stmt; |
| 1844 | int const nPixelsPerEvent = 1; /* for sizing the "graph" part */ |
| 1845 | int nRowNumber = 0; /* current TR number */ |
| 1846 | int nEventTotal = 0; /* Total event count */ |
| 1847 | int rowClass = 0; /* counter for alternating |
| @@ -1941,37 +1941,100 @@ | |
| 1941 | @ <td colspan='3'>Total events: %d(nEventTotal)</td> |
| 1942 | @ </tr> |
| 1943 | @ </tbody></table> |
| 1944 | db_finalize(&query); |
| 1945 | } |
| 1946 | |
| 1947 | /* |
| 1948 | ** WEBPAGE: stats_report |
| 1949 | ** |
| 1950 | ** Shows activity reports for the repository. |
| 1951 | ** |
| 1952 | ** Query Parameters: |
| 1953 | ** |
| 1954 | ** view=REPORT_NAME Valid values: bymonth, byyear |
| 1955 | ** user=NAME Restricts statistics to the given user |
| 1956 | */ |
| 1957 | void stats_report_page(){ |
| 1958 | HQuery url; /* URL for various branch links */ |
| 1959 | char const * zView = PD("view","bymonth"); /* Which view/report to show. */ |
| 1960 | char const *zUserName = P("user"); |
| 1961 | url_initialize(&url, "stats_report"); |
| 1962 | if(zUserName && *zUserName){ |
| 1963 | url_add_parameter(&url,"user", zUserName); |
| 1964 | } |
| 1965 | timeline_submenu(&url, "By Year", "view", "byyear", 0); |
| 1966 | timeline_submenu(&url, "By Month", "view", "bymonth", 0); |
| 1967 | url_reset(&url); |
| 1968 | style_header("Activity Reports"); |
| 1969 | if(0==fossil_strcmp(zView,"bymonth")){ |
| 1970 | stats_report_bymonthyear(1, zUserName); |
| 1971 | }else if(0==fossil_strcmp(zView,"byyear")){ |
| 1972 | stats_report_bymonthyear(0, zUserName); |
| 1973 | }else if(0==fossil_strcmp(zView,"byweek")){ |
| 1974 | @ TODO: by-week report. |
| 1975 | } |
| 1976 | style_footer(); |
| 1977 | } |
| 1978 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -1836,12 +1836,12 @@ | |
| 1836 | ** If includeMonth is true then it generates the "bymonth" report, |
| 1837 | ** else the "byyear" report. If zUserName is not NULL and not empty |
| 1838 | ** then the report is restricted to events created by the named user |
| 1839 | ** account. |
| 1840 | */ |
| 1841 | static void stats_report_by_month_year(char includeMonth, |
| 1842 | char const * zUserName){ |
| 1843 | Stmt query = empty_Stmt; |
| 1844 | int const nPixelsPerEvent = 1; /* for sizing the "graph" part */ |
| 1845 | int nRowNumber = 0; /* current TR number */ |
| 1846 | int nEventTotal = 0; /* Total event count */ |
| 1847 | int rowClass = 0; /* counter for alternating |
| @@ -1941,37 +1941,100 @@ | |
| 1941 | @ <td colspan='3'>Total events: %d(nEventTotal)</td> |
| 1942 | @ </tr> |
| 1943 | @ </tbody></table> |
| 1944 | db_finalize(&query); |
| 1945 | } |
| 1946 | |
| 1947 | void stats_report_by_user(){ |
| 1948 | Stmt query = empty_Stmt; |
| 1949 | int const nPixelsPerEvent = 1; /* for sizing the "graph" part */ |
| 1950 | int nRowNumber = 0; /* current TR number */ |
| 1951 | int nEventTotal = 0; /* Total event count */ |
| 1952 | int rowClass = 0; /* counter for alternating |
| 1953 | row colors */ |
| 1954 | Blob sql = empty_blob; /* SQL */ |
| 1955 | blob_append(&sql, |
| 1956 | "SELECT user, " |
| 1957 | "COUNT(*) AS eventCount " |
| 1958 | "FROM event " |
| 1959 | "GROUP BY user ORDER BY user", |
| 1960 | -1); |
| 1961 | db_prepare(&query, blob_str(&sql)); |
| 1962 | blob_reset(&sql); |
| 1963 | @ <h1>Timeline Events by User</h1> |
| 1964 | @ <table class='statistics-report-table-events' border='0' cellpadding='2' cellspacing='0'> |
| 1965 | @ <thead> |
| 1966 | @ <th>User</th> |
| 1967 | @ <th>Events</th> |
| 1968 | @ <th><!-- relative commits graph --></th> |
| 1969 | @ </thead><tbody> |
| 1970 | while( SQLITE_ROW == db_step(&query) ){ |
| 1971 | char const * zUser = db_column_text(&query, 0); |
| 1972 | int const nCount = db_column_int(&query, 1); |
| 1973 | int const nSize = 1+((nPixelsPerEvent * nCount) / 10); |
| 1974 | if(!nCount) continue; |
| 1975 | rowClass = ++nRowNumber % 2; |
| 1976 | nEventTotal += nCount; |
| 1977 | @<tr class='row%d(rowClass)'> |
| 1978 | @ <td> |
| 1979 | @ <a href="?view=byyear&user=%h(zUser)" target="_new">%s(zUser)</a> |
| 1980 | @ </td><td>%d(nCount)</td> |
| 1981 | @ <td> |
| 1982 | @ <div class='statistics-report-graph-line' style='height:16px; width:%d(nSize)px;'> |
| 1983 | @ </div></td> |
| 1984 | @</tr> |
| 1985 | /* |
| 1986 | Potential improvement: calculate the min/max event counts and |
| 1987 | use percent-based graph bars. |
| 1988 | */ |
| 1989 | } |
| 1990 | |
| 1991 | rowClass = ++nRowNumber % 2; |
| 1992 | @ <tr class='row%d(rowClass)'> |
| 1993 | @ <td colspan='3'>Total events: %d(nEventTotal)</td> |
| 1994 | @ </tr> |
| 1995 | @ </tbody></table> |
| 1996 | db_finalize(&query); |
| 1997 | } |
| 1998 | |
| 1999 | /* |
| 2000 | ** WEBPAGE: stats_report |
| 2001 | ** |
| 2002 | ** Shows activity reports for the repository. |
| 2003 | ** |
| 2004 | ** Query Parameters: |
| 2005 | ** |
| 2006 | ** view=REPORT_NAME Valid values: bymonth, byyear, byuser |
| 2007 | ** user=NAME Restricts statistics to the given user |
| 2008 | */ |
| 2009 | void stats_report_page(){ |
| 2010 | HQuery url; /* URL for various branch links */ |
| 2011 | char const * zView = PD("view","bymonth"); /* Which view/report to show. */ |
| 2012 | char const *zUserName = P("user"); |
| 2013 | int whichReport = 0; |
| 2014 | url_initialize(&url, "stats_report"); |
| 2015 | /* We have to figure out which report to run before continuing so |
| 2016 | that we can add (or not) the user= param to the buttons in a sane |
| 2017 | manner. |
| 2018 | */ |
| 2019 | if(zUserName && *zUserName){ |
| 2020 | url_add_parameter(&url,"user", zUserName); |
| 2021 | } |
| 2022 | timeline_submenu(&url, "By Year", "view", "byyear", 0); |
| 2023 | timeline_submenu(&url, "By Month", "view", "bymonth", 0); |
| 2024 | timeline_submenu(&url, "By User", "view", "byuser", "user"); |
| 2025 | url_reset(&url); |
| 2026 | style_header("Activity Reports"); |
| 2027 | if(0==fossil_strcmp(zView,"byyear")){ |
| 2028 | stats_report_by_month_year(0, zUserName); |
| 2029 | }else if(0==fossil_strcmp(zView,"bymonth")){ |
| 2030 | stats_report_by_month_year(1, zUserName); |
| 2031 | }else if(0==fossil_strcmp(zView,"byweek")){ |
| 2032 | @ TODO: by-week report. |
| 2033 | }else if(0==fossil_strcmp(zView,"byuser")){ |
| 2034 | stats_report_by_user(); |
| 2035 | }else{ |
| 2036 | @ TODO: show report select list. |
| 2037 | } |
| 2038 | |
| 2039 | style_footer(); |
| 2040 | } |
| 2041 |