public async Task <IActionResult> Stats( [FromServices] IMarkdownRenderer renderer, [FromServices] IGit git, [FromQuery] string q, [FromQuery] string since, [FromQuery] string until, [FromQuery] string author ) { var logArgs = Utils.SplitArguments(q).Concat(new[] { Param(nameof(since), since), Param(nameof(until), until), Param(nameof(author), author) }.WhereValue()).ToArray(); var c = git.GetChanges(logArgs); var byName = c.GroupBy(_ => _.Commit.author.Email) .Select(_ => new { User = _.Key, AddedLines = _.Sum(_c => _c.Stats.AddedLines), RemovedLines = _.Sum(_c => _c.Stats.RemovedLines) }) .OrderByDescending(_ => _.AddedLines + _.RemovedLines) .ToList(); var byPath = c .SelectMany(_ => ContentPath.FromUrlPath(_.Stats.Path).Lineage .Select(dir => new { Path = dir, Change = _ })) .GroupBy(_ => _.Path) .Select(_ => new { Path = _.Key, AddedLines = _.Sum(_c => _c.Change.Stats.AddedLines), RemovedLines = _.Sum(_c => _c.Change.Stats.RemovedLines) }) .OrderByDescending(_ => _.AddedLines) .Take(100) .ToList(); var markdown = $@" <form action=""/stats"" method=""get"" > <input name=""since"" placeholder=""since yyyy-mm-dd"" value={Attribute(since)} /> <input name=""until"" placeholder=""until yyyy-mm-dd"" value={Attribute(until)} /> <input name=""author"" placeholder=""author"" value={Attribute(author)} /> <input type=""submit"" /> </form> ## By User {byName.MarkdownTable() .With("User", _ => $"[{_.User}](/stats?author={_.User})") .With("Added Lines", _ => _.AddedLines) .With("Removed Lines", _ => _.RemovedLines) } ## By Path {byPath.MarkdownTable() .With("Path", _ => $"[{_.Path}](/{_.Path})") .With("Added Lines", _ => _.AddedLines) .With("Removed Lines", _ => _.RemovedLines) } "; return(await MarkdownView(renderer, new ContentPath(), markdown)); }