38 Commits

Author SHA1 Message Date
Shannon d5b0abd1ae fixing search 2017-06-27 10:42:37 +10:00
Niels Hartvig 81ba5bd022 Merge pull request #118 from bjarnef/dev-OUR-451-update
Update Fancybox to latest v3
2017-06-26 14:57:38 +02:00
Bjarne Fyrstenborg 96a3ca71a7 Update Fancybox to latest v3 2017-06-23 17:30:45 +02:00
Niels Hartvig a8e253553a Removes people with 0 contributions from list 2017-06-23 13:16:59 +02:00
Niels Hartvig 91280b18f6 Fix from Pull Request #84 2017-06-23 12:59:02 +02:00
Niels Hartvig fbb8ef1ba0 Merge pull request #100 from stvnhrlnd/OUR-441
Our 441
2017-06-23 12:03:02 +02:00
Niels Hartvig 3f46d94a93 Merge branch 'naepalm-feature-icon-size-tweaks' 2017-06-23 11:50:56 +02:00
Niels Hartvig 161fcc7f01 Updates PR with bjarnef's review comments 2017-06-23 11:50:34 +02:00
Niels Hartvig 5e2cb68299 Merge branch 'feature-icon-size-tweaks' of https://github.com/naepalm/OurUmbraco into naepalm-feature-icon-size-tweaks 2017-06-23 11:28:29 +02:00
Niels Hartvig e6a5b59ac6 Merge pull request #117 from umbraco/temp-OUR-456
Removes RTs from twitter feed
2017-06-23 11:26:43 +02:00
Niels Hartvig 2ffa61564c Removes RTs from twitter feed 2017-06-23 11:03:06 +02:00
Niels Hartvig a1d48afeca Merge pull request #106 from bjarnef/dev-OUR-451
Update to FancyBox v3
2017-06-23 10:55:13 +02:00
Niels Hartvig a51e57737b Merge branch 'bjarnef-dev-githubfilecache' 2017-06-23 10:48:42 +02:00
Niels Hartvig 1c8fcef754 Removing throwing error upon github api not returning 200
(we already log it and the Accepted status with empty data set is
(hopefully) a throttle issue)
2017-06-23 10:47:50 +02:00
Niels Hartvig ab4ca0015e Merge with master 2017-06-23 10:38:52 +02:00
Niels Hartvig f9014d649b Fixes issue with contrib not counting commits but additions+deletions 2017-06-23 10:09:04 +02:00
hartvig adf67fd89f Merge pull request #116 from Weegy/GitGubContributors
Git gub contributors
2017-06-23 08:54:03 +02:00
Sebastiaan Janssen 805709a91b Set frontend auth cookie to be sent over secure channel only 2017-06-23 08:22:44 +02:00
Marcel Wege 40a6aaa1a8 foreach to Linq.SUM 2017-06-22 17:29:57 +02:00
Marcel Wege 5e51dad445 GitHubContributors 2017-06-22 16:56:35 +02:00
hartvig f2d9cc0c0b Merge pull request #110 from emmagarland/githubcontributors
Github contributors
2017-06-22 14:43:45 +02:00
Niels Hartvig a40f8f9a28 Fixes cache setting 2017-06-22 14:39:38 +02:00
Niels Hartvig 355c4184ef Update github list to only include people from the last 12 months 2017-06-22 14:37:32 +02:00
Sebastiaan Janssen 50bdd7647a Redirect docs for products to Add-on 2017-06-22 10:16:14 +02:00
hartvig 47c85e633b Adding umbLeeds to meetup list 2017-06-19 15:31:34 +02:00
Sebastiaan Janssen f82cda981c Whitelist branches to get the documentation from and make it a little bit safer (don't start with deleting everything until we're pretty sure it's going to be rebuilt correctly afterwards). 2017-06-13 13:35:55 +02:00
Sebastiaan Janssen aded9ec437 Fixing docs 2017-06-13 10:17:45 +02:00
Shannon bdcad7665f fixes string interpolation 2017-06-07 08:34:12 +02:00
Per Ploug 850b61fc4f Merge pull request #114 from umbraco/lesson-documentation-controller
remove dollars
2017-06-07 08:04:30 +02:00
Bjarne Fyrstenborg 1ea05d8107 Write contributors to json file and use file cached disk value 2017-06-06 16:27:21 +02:00
Emma Garland 60b7347586 Updated contributions to commits 2017-06-05 20:55:12 +01:00
Emma Garland b35d45bf31 Updated contribution link 2017-06-05 20:38:26 +01:00
Bjarne Fyrstenborg e3c52baf3a Update to FancyBox v3 2017-05-15 19:12:35 +02:00
Janae Cram 0cef4124db Fixes issue #OUR-449. 2017-05-05 13:13:43 -07:00
Steven 87847769ce Update forum partial
Show next page link when current page is less than the total number of pages. Keeps pagination consistent with projects list.
2017-03-04 15:43:46 +00:00
Steven 49c50046c9 Update search JavaScript
Reset page number to 1 when search filters are changed.
2017-03-04 15:11:22 +00:00
Steven c93e4d1e2d Update topic service and forum partial to fix pagination issue
Add new parameters to count method for unsolved and no reply filters. Update view to pass in these parameters.
2017-03-04 14:50:46 +00:00
Steven 686e3deb6c Update forum pagination links
Preserve query string parameters in pagination links so that topic filters do not get reset when switching between pages.
2017-03-04 14:23:19 +00:00
20 changed files with 456 additions and 257 deletions
+3 -2
View File
@@ -62,7 +62,7 @@ function GetSearchFilters(cssClass) {
}
var forumId = $('#selectCategory').val();
if(forumId !== undefined) {
if(forumId) {
forumId = forumId.replace(/([A-Za-z])\w+/g, "");
}
@@ -365,7 +365,8 @@ $('#search-options input[type=checkbox]').click(function () {
newUri = updateQueryString("order", orderValue, window.location.href);
}
} else {
newUri = updateQueryString(this.name, this.checked, window.location.href);
newUri = updateQueryString(this.name, this.checked, window.location.href);
newUri = updateQueryString("page", 1, newUri);
}
console.log(newUri);
window.location = newUri;
+171 -171
View File
@@ -1,174 +1,174 @@
body.packages {
nav {
h3 {
&:hover {
opacity: .8;
}
}
h4 {
opacity: .7;
margin: .5rem 0 .5rem;
}
}
li {
h3 {
opacity: .5;
}
&.open, &.active {
h3, a {
opacity: 1;
color: #000 !important;
}
}
&.active > ul {
max-height: 100%;
}
}
}
.packages-content {
.search-big {
margin-bottom: 0;
margin-top: 20px;
}
h1 {
margin: 1em 0 10px;
font-size: 2.1rem;
}
.package {
margin-bottom: 15px;
padding: 20px;
transition: all .1s linear;
cursor: pointer;
position: relative;
overflow: hidden;
border-radius: 3px;
border: 1px solid #e9e9e9;
&:hover {
@include box-shadow(2);
.icon {
transform: scale(1.1);
}
}
}
.box {
border: none;
border-bottom: 1px solid whitesmoke;
width: 100%;
body.packages {
nav {
h3 {
&:hover {
opacity: .8;
}
}
h4 {
opacity: .7;
margin: .5rem 0 .5rem;
}
}
li {
h3 {
opacity: .5;
}
&.open, &.active {
h3, a {
opacity: 1;
color: #000 !important;
}
}
&.active > ul {
max-height: 100%;
}
}
}
.packages-content {
.search-big {
margin-bottom: 0;
margin-top: 20px;
}
h1 {
margin: 1em 0 10px;
font-size: 2.1rem;
}
.package {
margin-bottom: 15px;
padding: 20px;
transition: all .1s linear;
cursor: pointer;
position: relative;
overflow: hidden;
border-radius: 3px;
border: 1px solid #e9e9e9;
&:hover {
@include box-shadow(2);
.icon {
transform: scale(1.1);
}
}
}
.box {
border: none;
border-bottom: 1px solid whitesmoke;
width: 100%;
.row{
width:100%;
}
h3 {
font-size: 1.1rem;
margin-bottom: .5rem;
font-weight: 600;
a {
color: $color-headline;
&:hover {
color: $color-our;
}
}
}
img {
max-width: 100%;
height: auto;
display: block;
vertical-align: middle;
@media (min-width: $md) {
}
}
.col-xs-2 {
vertical-align: middle !important;
padding: 0 !important;
}
.other {
margin-top: 30px;
}
.stats {
left: calc(16.666666666666664% + 15px);
font-family: Consolas, "Liberation Mono", Menlo, Monaco, Courier, monospace;
font-size: .75rem;
i {
margin-left: 3px;
font-size: .9rem;
}
span {
&:first-child {
margin-right: 0px;
}
}
}
p {
font-size: .9rem;
color: $color-text;
opacity: 1;
}
.package-badge {
position: absolute;
right: 15px;
bottom: -3px;
@media (min-width: $md) {
position: absolute;
right: 0;
bottom: 25px;
}
}
.karma , .downloads {
color: #000;
span {
transform: translate(0, 2px);
display: inline-block;
}
}
&.liked {
.karma {
i {
color: $color-red;
}
}
}
}
.name {
font-size: 1rem;
line-height: 1.3;
font-weight: bold;
}
.description {
font-size: .8rem;
margin-top: 3px;
max-height: 28px;
overflow: hidden;
}
}
h3 {
font-size: 1.1rem;
margin-bottom: .5rem;
font-weight: 600;
a {
color: $color-headline;
&:hover {
color: $color-our;
}
}
}
img {
max-width: 100%;
height: auto;
display: block;
vertical-align: middle;
@media (min-width: $md) {
}
}
.col-xs-2 {
vertical-align: middle !important;
padding: 0 !important;
}
.other {
margin-top: 30px;
}
.stats {
left: calc(16.666666666666664% + 15px);
font-family: Consolas, "Liberation Mono", Menlo, Monaco, Courier, monospace;
font-size: .75rem;
i {
margin-left: 3px;
font-size: .9rem;
}
span {
&:first-child {
margin-right: 0px;
}
}
}
p {
font-size: .9rem;
color: $color-text;
opacity: 1;
}
.package-badge {
position: absolute;
right: 15px;
bottom: -3px;
@media (min-width: $md) {
position: absolute;
right: 0;
bottom: 25px;
}
}
.karma , .downloads {
color: #000;
span {
transform: translate(0, 2px);
display: inline-block;
}
}
&.liked {
.karma {
i {
color: $color-red;
}
}
}
}
.name {
font-size: 1rem;
line-height: 1.3;
font-weight: bold;
}
.description {
font-size: .8rem;
margin-top: 3px;
max-height: 28px;
overflow: hidden;
}
}
@@ -157,6 +157,10 @@ section.forum {
max-width: 112px;
height: auto;
.package-forum-activity & {
border-radius: 0;
}
@media (min-width: $md) {
width: 58px;
}
+3 -3
View File
@@ -14,7 +14,7 @@
Html.RequiresCss("~/assets/css/style.min.css", 0);
Html.RequiresCss("https://fonts.googleapis.com/css?family=Asap:400,700,400italic,700italic", 0);
Html.RequiresCss("https://cdnjs.cloudflare.com/ajax/libs/fancybox/2.1.5/jquery.fancybox.min.css", 0);
Html.RequiresCss("https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.1.20/jquery.fancybox.min.css", 0);
Html.RequiresJs("https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.13.1/jquery.validate.min.js");
@@ -23,7 +23,7 @@
Html.RequiresJs("https://cdnjs.cloudflare.com/ajax/libs/pagedown/1.0/Markdown.Editor.js");
Html.RequiresJs("https://cdnjs.cloudflare.com/ajax/libs/pagedown/1.0/Markdown.Sanitizer.js");
Html.RequiresJs("https://cdnjs.cloudflare.com/ajax/libs/mustache.js/0.8.1/mustache.min.js");
Html.RequiresJs("https://cdnjs.cloudflare.com/ajax/libs/fancybox/2.1.5/jquery.fancybox.min.js");
Html.RequiresJs("https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.1.20/jquery.fancybox.min.js");
Html.RequiresJs("~/assets/js/jquery.ajaxfileupload.js");
@@ -90,7 +90,7 @@
<!--[if lt IE 9]>
<script src="https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.7.1/modernizr.min.js"></script>
<![endif]-->
<script type="text/javascript" src="https://code.jquery.com/jquery-1.7.2.min.js"></script>
<script type="text/javascript" src="https://code.jquery.com/jquery-1.9.1.min.js"></script>
@Html.Partial("~/Views/Partials/Community/JsValues.cshtml")
@@ -140,7 +140,6 @@ else
<div class="col-md-12">
<h1 class="text-center">GitHub Contributions</h1>
<p>
Contributions to Umbraco GitHub repositories
<small class="link-list">
Contributions to default branches for
<a href="https://github.com/umbraco/Umbraco-CMS" target="_blank" title="Umbraco-CMS">Umbraco-CMS</a>,
@@ -153,7 +152,7 @@ else
</p>
</div>
<div class="col-md-12">
<small>GitHub contributors</small>
<small>Contributions the last 12 months (number indicating accepted commits)</small>
</div>
<div class="col-md-12 flex forum-thread" id="github-contributors">
@@ -161,7 +160,7 @@ else
</div>
<div class="col-md-12 goto-forum">
<a class="button green" href="https://github.com/umbraco" target="_blank">Contribute to Umbraco on GitHub &rarr;</a>
<a class="button green" href="https://our.umbraco.org/contribute">Contribute to Umbraco &rarr;</a>
</div>
</div>
@@ -5,6 +5,9 @@
@inherits OurUmbraco.Our.Models.OurUmbracoTemplatePage
@{
// Save query string for use in pagination links
var queryString = HttpUtility.ParseQueryString(Request.QueryString.ToString());
const int pagesToShowLeft = 4;
int page;
if (!int.TryParse(Request["page"], out page))
@@ -40,9 +43,9 @@
TimeSpan.FromSeconds(4));
}
var totalCountKey = "OurForumForumThreadCount[" + cat + "]";
var totalCountKey = "OurForumForumThreadCount[" + cat + unsolved + noreplies + "]";
var totalTopics = (int)cache.GetCacheItem(totalCountKey,
() => topicService.GetAllTopicsCount(cat),
() => topicService.GetAllTopicsCount(cat, unsolved, noreplies),
TimeSpan.FromMinutes(1));
var pages = (totalTopics / pageSize) + 1;
@@ -168,19 +171,22 @@
<nav class="pagination" role="navigation">
@if (page > 1)
{
<a class="prev" href="?page=@(page - 1)">Prev</a>
queryString["page"] = (page - 1).ToString();
<a class="prev" href="?@queryString">Prev</a>
<span>&hellip;</span>
}
@for (var i = (page - 1 > 0 ? page - 1 : 1); i < (page + (pagesToShowLeft - (page - 1 > 0 ? 1 : 0))) && i <= pages; i++)
{
<a class="@Umbraco.If(i == page, "active")" href="?page=@i">@i</a>
queryString["page"] = i.ToString();
<a class="@Umbraco.If(i == page, "active")" href="?@queryString">@i</a>
}
@if (page < (pages - 3))
@if (page < pages)
{
queryString["page"] = (page + 1).ToString();
<span>&hellip;</span>
<a class="next" href="?page=@(page + 1)">Next</a>
<a class="next" href="?@queryString">Next</a>
}
</nav>
@@ -4,12 +4,10 @@
{
foreach (var contributor in Model.Contributors)
{
var author = contributor.Author;
if (author != null)
{
<a href="@author.HtmlUrl" class="contributor" target="_blank" title="@author.Login">
<a href="@contributor.AuthorUrl" class="contributor" target="_blank" title="@contributor.AuthorLogin">
<div class="avatar">
<img alt="@author.Login" src="@author.AvatarUrl&s=112" />
<img alt="@contributor.AuthorLogin" src="@contributor.AuthorAvatarUrl&s=112"
srcset="@contributor.AuthorAvatarUrl&s=224 2x, @contributor.AuthorAvatarUrl&s=336 3x" />
<span class="contrib-count" title="@(contributor.TotalCommits + " " + (contributor.TotalCommits == 1 ? "contribution" : "contributions"))">
@contributor.TotalCommits
</span>
@@ -22,7 +20,6 @@
</div>
</div>
</a>
}
}
<div class="loadmore">
<a class="button transparent" href="#" onclick="loadAllGitHubContributors(); return false;">Load more</a>
@@ -185,7 +185,9 @@
defaultScreenshot = childContent.GetPropertyValue("defaultScreenshotPath", false, "/css/img/package2.png");
}
}
<img src="@Utils.GetScreenshotPath(defaultScreenshot)?bgcolor=fff&width=50&height=50&format=png" />
<img src="@Utils.GetScreenshotPath(defaultScreenshot)?bgcolor=fff&width=50&height=50&format=png"
srcset="@Utils.GetScreenshotPath(defaultScreenshot)?bgcolor=fff&width=100&height=100&format=png 2x,
@Utils.GetScreenshotPath(defaultScreenshot)?bgcolor=fff&width=150&height=150&format=png 3x" />
</div>
<div class="col-xs-10 col-md-6">
<div class="forum-thread-text">
@@ -81,7 +81,7 @@
@foreach (var image in screenshots)
{
<a class="fancybox" rel="gallery1" href="@Utils.GetScreenshotPath(image.Path)" title="">
<a class="fancybox" data-fancybox="package-gallery" href="@Utils.GetScreenshotPath(image.Path)" title="">
<img src="@Utils.GetScreenshotPath(image.Path)?bgcolor=fff&height=154&width=281&format=png" alt=""/>
</a>
}
@@ -236,7 +236,7 @@
<a href="@forum.Url" class="forum-thread">
<div class="row">
<div class="col-xs-10 col-md-0">
<div class="col-xs-12 col-md-12">
<div class="forum-thread-text">
<h3>@forum.Name</h3>
<p>@forum.forumDescription</p>
+4 -3
View File
@@ -18,9 +18,10 @@
(function () {
$(".fancybox")
.fancybox({
openEffect: 'none',
closeEffect: 'none',
padding: 0
// options
loop: true,
arrows: true,
infobar: false
});
})();
</script>
@@ -32,4 +32,5 @@ UmbCardiff
meet-umbraco-the-umbraco-meetup
umBristol
Oslo-Umbraco-Meetup
Orange-County-Umbraco-Web-Technologies
Orange-County-Umbraco-Web-Technologies
umbLeeds
+2
View File
@@ -2,5 +2,7 @@
<configuration>
<sources>
<add url="https://github.com/umbraco/UmbracoDocs/archive/master.zip" folder="" />
<!-- Comma separated list of branches we will pull documentation from -->
<allowedBranches>master</allowedBranches>
</sources>
</configuration>
+6 -2
View File
@@ -308,7 +308,7 @@
</buildProviders>
</compilation>
<authentication mode="Forms">
<forms name="yourAuthCookie" loginUrl="login.aspx" protection="All" path="/" slidingExpiration="true" timeout="525600" />
<forms requireSSL="true" name="yourAuthCookie" loginUrl="login.aspx" protection="All" path="/" slidingExpiration="true" timeout="525600" />
</authentication>
<authorization>
<allow users="?" />
@@ -506,6 +506,10 @@
</conditions>
<action type="Redirect" url="{C:1}" redirectType="Permanent" appendQueryString="true" />
</rule>
<rule name="DocsProductsToAddons" patternSyntax="Wildcard" stopProcessing="true">
<match url="documentation/products/*" />
<action type="Redirect" url="/documentation/Add-ons/{R:1}" redirectType="Permanent" appendQueryString="true" />
</rule>
<!-- WIKI -->
<rule name="RedirectWikiEvents" patternSyntax="Wildcard">
<match url="wiki/reference/api-cheatsheet/using-applicationbase-to-register-events/*" />
@@ -691,4 +695,4 @@
</httpProtocol>
</system.webServer>
</location>
</configuration>
</configuration>
@@ -9,6 +9,9 @@ using RestSharp;
using Umbraco.Core.Cache;
using Umbraco.Core.Logging;
using Umbraco.Web.Mvc;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using System.Text;
namespace OurUmbraco.Community.Controllers
{
@@ -27,68 +30,144 @@ namespace OurUmbraco.Community.Controllers
"Umbraco.Deploy.ValueConnectors"
};
protected string JsonPath
{
get { return Server.MapPath("~/App_Data/TEMP/GithubContributors.json"); }
}
public List<GitHubCachedGlobalContributorModel> GetCachedContributors()
{
if (!System.IO.File.Exists(JsonPath)) throw new Exception("The JSON file doesn't exist on disk");
List<GitHubCachedGlobalContributorModel> temp = new List<GitHubCachedGlobalContributorModel>();
// Parse the JSON file from disk
foreach (JToken token in Skybrud.Essentials.Json.JsonUtils.LoadJsonArray(JsonPath))
{
temp.Add(token.ToObject<GitHubCachedGlobalContributorModel>());
}
return temp;
}
/// <summary>
/// Gets data for all GitHub contributors for all listed Umbraco repositories,
/// excluding the GitHub IDs of the HQ contributors from the text file list
/// </summary>
/// <returns></returns>
public ActionResult GitHubGetContributorsResult()
public ActionResult GitHubGetContributorsResult(bool force = false)
{
var model = new GitHubContributorsModel();
model.Contributors = new List<GitHubCachedGlobalContributorModel>();
try
{
string configPath = Server.MapPath("~/config/githubhq.txt");
if (!System.IO.File.Exists(configPath))
// If the file exists on disk and hasn't expired (AKA not older than one day), we should just load that
if (force == false && System.IO.File.Exists(JsonPath) && System.IO.File.GetLastWriteTimeUtc(JsonPath) >= DateTime.UtcNow.AddDays(-1))
{
LogHelper.Debug<GitHubContributorController>("Config file was not found: " + configPath);
model.Contributors = GetCachedContributors();
return PartialView("~/Views/Partials/Home/GitHubContributors.cshtml", model);
}
string[] login = System.IO.File.ReadAllLines(configPath).Where(x => x.Trim() != "").Distinct().ToArray();
var contributors = ApplicationContext.ApplicationCache.RuntimeCache.GetCacheItem<List<GitHubGlobalContributorModel>>("UmbracoGitHubContributors",
() =>
{
var githubController = new GitHubController();
var gitHubContributors = new List<GitHubContributorModel>();
foreach (var repo in Repositories)
{
var response = githubController.GetAllRepoContributors(repo);
if (response.StatusCode == HttpStatusCode.OK &&
response.ResponseStatus == ResponseStatus.Completed)
{
gitHubContributors.AddRange(response.Data);
}
else
{
LogHelper.Warn<IGitHubContributorsModel>(string.Format("Invalid HTTP response for repository {0}", repo));
}
}
try
{
// Load the contributors via the GitHub API and map to the cached model
var contributors = GetContributors().Select(x => new GitHubCachedGlobalContributorModel(x));
var filteredContributors = gitHubContributors
.Where(g => !login.Contains(g.Author.Login))
.GroupBy(g => g.Author.Id)
.OrderByDescending(c => c.Sum(g => g.Total));
// Serialize the contributors to raw JSON
string rawJson = JsonConvert.SerializeObject(contributors, Formatting.Indented);
List<GitHubGlobalContributorModel> temp = new List<GitHubGlobalContributorModel>();
// Save the JSON to disk
System.IO.File.WriteAllText(JsonPath, rawJson, Encoding.UTF8);
foreach (var group in filteredContributors)
{
temp.Add(new GitHubGlobalContributorModel(group));
}
model.Contributors = contributors.ToList();
}
catch (Exception ex)
{
// Log the error so we can debug it later
LogHelper.Error<GitHubContributorController>("Unable to load GitHub contributors from the GitHub API", ex);
return temp;
// Load the contributors from the cache (if we have any)
model.Contributors = GetCachedContributors();
}
}, TimeSpan.FromDays(1));
model.Contributors = contributors;
}
catch (Exception ex)
{
LogHelper.Error<IGitHubContributorsModel>("Could not get GitHub Contributors", ex);
// Log the error so we can debug it later
LogHelper.Error<GitHubContributorController>("Unable to load GitHub contributors from the GitHub API", ex);
}
return PartialView("~/Views/Partials/Home/GitHubContributors.cshtml", model);
}
public List<GitHubGlobalContributorModel> GetContributors()
{
string configPath = Server.MapPath("~/config/githubhq.txt");
if (!System.IO.File.Exists(configPath))
{
LogHelper.Debug<GitHubContributorController>("Config file was not found: " + configPath);
throw new Exception("Config file was not found: " + configPath);
}
string[] login = System.IO.File.ReadAllLines(configPath).Where(x => x.Trim() != "").Distinct().ToArray();
var githubController = new GitHubController();
var gitHubContributors = new List<GitHubContributorModel>();
foreach (var repo in Repositories)
{
var response = githubController.GetAllRepoContributors(repo);
if (response.StatusCode == HttpStatusCode.OK &&
response.ResponseStatus == ResponseStatus.Completed)
{
gitHubContributors.AddRange(response.Data);
}
else
{
LogHelper.Warn<IGitHubContributorsModel>(string.Format("Invalid HTTP response for repository {0}", repo));
}
}
// filter to only include items from the last year (if we ran 4.6.1 we could have used ToUnixTimeSeconds())
var filteredRange = DateTime.UtcNow.AddYears(-1).Subtract(new DateTime(1970, 1, 1)).TotalSeconds;
foreach (var contrib in gitHubContributors)
{
var contribWeeks = contrib.Weeks.Where(x => x.W >= filteredRange).ToList();
contrib.TotalAdditions = contribWeeks.Sum(x => x.A);
contrib.TotalDeletions = contribWeeks.Sum(x => x.D);
contrib.Total = contribWeeks.Sum(x => x.C);
}
var filteredContributors = gitHubContributors
.Where(g => !login.Contains(g.Author.Login))
.GroupBy(g => g.Author.Id)
.OrderByDescending(c => c.Sum(g => g.Total));
List<GitHubGlobalContributorModel> temp = new List<GitHubGlobalContributorModel>();
foreach (var group in filteredContributors)
{
var contributor = new GitHubGlobalContributorModel(group);
if (contributor.TotalCommits > 0)
{
temp.Add(contributor);
}
}
return temp;
}
}
}
@@ -4,6 +4,39 @@ using OurUmbraco.Community.Models;
namespace OurUmbraco.Community.Controllers
{
public class GitHubCachedGlobalContributorModel
{
public int AuthorId { get; set; }
public string AuthorLogin { get; set; }
public string AuthorUrl { get; set; }
public string AuthorAvatarUrl { get; set; }
public int TotalCommits { get; set; }
public int TotalAdditions { get; set; }
public int TotalDeletions { get; set; }
public GitHubCachedGlobalContributorModel() { }
public GitHubCachedGlobalContributorModel(GitHubGlobalContributorModel contributor)
{
AuthorId = contributor.Author.Id;
AuthorLogin = contributor.Author.Login;
AuthorUrl = contributor.Author.HtmlUrl;
AuthorAvatarUrl = contributor.Author.AvatarUrl;
TotalCommits = contributor.TotalCommits;
TotalAdditions = contributor.TotalAdditions;
TotalDeletions = contributor.TotalDeletions;
}
}
public class GitHubGlobalContributorModel
{
public List<GitHubContributorModel> Items { get; set; }
@@ -60,7 +60,8 @@ namespace OurUmbraco.Community.Controllers
x.CreatedBy.UserIdentifier.ScreenName.ToLowerInvariant().ContainsAny(usernameFilter) ==
false
&& x.UserMentions.Any(m => m.ScreenName.ContainsAny(usernameFilter)) == false
&& x.Text.ToLowerInvariant().ContainsAny(wordFilter) == false)
&& x.Text.ToLowerInvariant().ContainsAny(wordFilter) == false
&& x.Text.StartsWith("RT ") == false)
.Take(numberOfResults)
.ToArray();
}
@@ -5,6 +5,6 @@ namespace OurUmbraco.Community.Models
{
public class GitHubContributorsModel : IGitHubContributorsModel
{
public List<GitHubGlobalContributorModel> Contributors { get; set; }
public List<GitHubCachedGlobalContributorModel> Contributors { get; set; }
}
}
@@ -3,13 +3,10 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Net;
using System.Web;
using System.Web.Hosting;
using System.Xml;
using Examine;
using ICSharpCode.SharpZipLib.Zip;
using Newtonsoft.Json;
using Umbraco.Core.Logging;
using ZipFile = System.IO.Compression.ZipFile;
@@ -122,10 +119,36 @@ namespace OurUmbraco.Documentation.Busineslogic.GithubSourcePull
public void Process(string url, string foldername)
{
var zip = Download(url, foldername);
RemoveExistingDocumentation(RootFolder);
var unzippedPath = string.Empty;
var branchAllowed = false;
using (var zipFile = ZipFile.OpenRead(zip))
{
var directory = zipFile.Entries.FirstOrDefault();
if (directory != null)
{
var branch = directory.FullName.Replace("/", string.Empty).Replace("UmbracoDocs-", string.Empty);
branchAllowed = IsBranchWhiteListed(branch);
if (branchAllowed)
{
unzippedPath = RootFolder + Path.DirectorySeparatorChar +
directory.FullName.Replace('/', Path.DirectorySeparatorChar);
if (Directory.Exists(unzippedPath))
//delete the directory we're trying to unzip to
RemoveUnzippedFiles(unzippedPath);
}
}
}
if (branchAllowed == false)
return;
ZipFile.ExtractToDirectory(zip, RootFolder);
var unzippedPath = RootFolder + "\\UmbracoDocs-StarterkitLessons\\";
RemoveUnzippedFiles(RootFolder, ignoreDirectories: new List<string> { unzippedPath });
foreach (var directory in new DirectoryInfo(unzippedPath).GetDirectories())
Directory.Move(directory.FullName, RootFolder + "\\" + directory.Name);
foreach (var file in new DirectoryInfo(unzippedPath).GetFiles())
@@ -139,6 +162,25 @@ namespace OurUmbraco.Documentation.Busineslogic.GithubSourcePull
ExamineManager.Instance.IndexProviderCollection["documentationIndexer"].RebuildIndex();
}
private bool IsBranchWhiteListed(string branch)
{
var xmlNodeList = Configuration.SelectNodes("//allowedBranches");
if (xmlNodeList == null || xmlNodeList.Count <= 0)
return false;
var node = xmlNodeList[0];
if (string.IsNullOrWhiteSpace(node.InnerText))
return false;
var allowedBranches = node.InnerText.Split(',');
var isBranchWhitelisted = allowedBranches.Any(allowedBranch => allowedBranch.Equals(branch, StringComparison.InvariantCultureIgnoreCase));
if (isBranchWhitelisted == false)
LogHelper.Warn<ZipDownloader>(string.Format("The branch {0} is not allowed in githubpull.config, will not process documentation any further", branch));
return isBranchWhitelisted;
}
public void BuildSitemap(string foldername)
{
var folder = new DirectoryInfo(Path.Combine(RootFolder, foldername));
@@ -158,7 +200,7 @@ namespace OurUmbraco.Documentation.Busineslogic.GithubSourcePull
public List<SiteMapItem> directories { get; set; }
//public string url => $"http://localhost:24292/documentation{this.path}/?altTemplate=Lesson";
public string url
{
get
@@ -181,7 +223,7 @@ namespace OurUmbraco.Documentation.Busineslogic.GithubSourcePull
directories = list,
hasChildren = dir.GetDirectories().Any()
};
foreach (var child in dir.GetDirectories().Where(x => x.Name != "images"))
{
list.Add(GetFolderStructure(child, rootPath, level + 1));
@@ -452,21 +494,35 @@ namespace OurUmbraco.Documentation.Busineslogic.GithubSourcePull
return path;
}
private static void RemoveExistingDocumentation(string folder)
private static void RemoveUnzippedFiles(string folder, List<string> ignoreDirectories = null)
{
if (Directory.Exists(folder))
{
foreach (var directory in Directory.GetDirectories(folder))
Retry.Do(() => Directory.Delete(directory, true), TimeSpan.FromSeconds(1), 5);
{
if (ignoreDirectories == null || ignoreDirectories.Any() == false)
{
//there are no ignores, so proceed to delete it
Retry.Do(() => Directory.Delete(directory, true), TimeSpan.FromSeconds(1), 5);
}
else
{
foreach (var ignoreDirectory in ignoreDirectories)
{
if (ignoreDirectory.TrimEnd('\\').Equals(directory.TrimEnd('\\'),
StringComparison.InvariantCultureIgnoreCase) == false)
{
//path is NOT in the ignore list, so proceed to delete it
Retry.Do(() => Directory.Delete(directory, true), TimeSpan.FromSeconds(1), 5);
}
}
}
}
foreach (var mdfile in Directory.GetFiles(folder, "*.md"))
Retry.Do(() => File.Delete(mdfile), TimeSpan.FromSeconds(1), 5);
}
else
{
Directory.CreateDirectory(folder);
}
}
private readonly Events _events = new Events();
@@ -1,4 +1,5 @@
using System.IO;
using System;
using System.IO;
using System.Text.RegularExpressions;
using MarkdownDeep;
@@ -85,7 +86,7 @@ namespace OurUmbraco.Documentation.Busineslogic
//Need to ensure we dont append the image links as they 404 if we add altTemplate
if (AppendAltLessonLink && rawUrl.StartsWith("images/") == false)
{
return mdUrlTag.Replace(rawUrl, $"{rawUrl.EnsureNoDotsInUrl()}?altTemplate=Lesson");
return mdUrlTag.Replace(rawUrl, string.Format("{0}?altTemplate=Lesson", rawUrl.EnsureNoDotsInUrl()));
}
return mdUrlTag.Replace(rawUrl, rawUrl.EnsureNoDotsInUrl());
+13 -1
View File
@@ -123,7 +123,7 @@ FETCH NEXT @count ROWS ONLY";
/// </summary>
/// <param name="category"></param>
/// <returns></returns>
public int GetAllTopicsCount(int category = -1)
public int GetAllTopicsCount(int category = -1, bool unsolved = false, bool noreplies = false)
{
const string sql1 = @"SELECT COUNT(*) as forumTopicCount
FROM forumTopics
@@ -135,6 +135,18 @@ LEFT OUTER JOIN umbracoNode u2 ON (forumTopics.memberId = u2.id AND u2.nodeObjec
var sql = (category > 0 ? sqlic : sqlix);
if (unsolved)
if (sql.Contains("WHERE"))
sql = sql + " AND answer = 0";
else
sql = sql + " WHERE answer = 0";
if (noreplies)
if (sql.Contains("WHERE"))
sql = sql + " AND replies = 0";
else
sql = sql + " WHERE replies = 0";
return _databaseContext.Database.ExecuteScalar<int>(sql, new { category = category });
}