Rename Model Classes; HTTP2 push; New date index

refactor-intermediate-models
Thomas Hounsell 2016-08-21 00:09:56 +01:00
parent adac13d855
commit 1531151259
24 changed files with 528 additions and 524 deletions

View File

@ -7,7 +7,7 @@ using MongoDB.Driver;
namespace BuildFeed.Model
{
public partial class Build
public partial class BuildRepository
{
public async Task<FrontBuildGroup[]> SelectAllGroups(int limit = -1, int skip = 0)
{
@ -16,12 +16,12 @@ namespace BuildFeed.Model
new BsonElement("_id",
new BsonDocument
{
new BsonElement(nameof(BuildGroup.Major), $"${nameof(BuildModel.MajorVersion)}"),
new BsonElement(nameof(BuildGroup.Minor), $"${nameof(BuildModel.MinorVersion)}"),
new BsonElement(nameof(BuildGroup.Build), $"${nameof(BuildModel.Number)}"),
new BsonElement(nameof(BuildGroup.Revision), $"${nameof(BuildModel.Revision)}")
new BsonElement(nameof(BuildGroup.Major), $"${nameof(Build.MajorVersion)}"),
new BsonElement(nameof(BuildGroup.Minor), $"${nameof(Build.MinorVersion)}"),
new BsonElement(nameof(BuildGroup.Build), $"${nameof(Build.Number)}"),
new BsonElement(nameof(BuildGroup.Revision), $"${nameof(Build.Revision)}")
}),
new BsonElement("date", new BsonDocument("$max", $"${nameof(BuildModel.BuildTime)}")),
new BsonElement("date", new BsonDocument("$max", $"${nameof(Build.BuildTime)}")),
new BsonElement("count", new BsonDocument("$sum", 1))
}).Sort(new BsonDocument
{
@ -60,26 +60,26 @@ namespace BuildFeed.Model
new BsonElement("_id",
new BsonDocument
{
new BsonElement(nameof(BuildGroup.Major), $"${nameof(BuildModel.MajorVersion)}"),
new BsonElement(nameof(BuildGroup.Minor), $"${nameof(BuildModel.MinorVersion)}"),
new BsonElement(nameof(BuildGroup.Build), $"${nameof(BuildModel.Number)}"),
new BsonElement(nameof(BuildGroup.Revision), $"${nameof(BuildModel.Revision)}")
new BsonElement(nameof(BuildGroup.Major), $"${nameof(Build.MajorVersion)}"),
new BsonElement(nameof(BuildGroup.Minor), $"${nameof(Build.MinorVersion)}"),
new BsonElement(nameof(BuildGroup.Build), $"${nameof(Build.Number)}"),
new BsonElement(nameof(BuildGroup.Revision), $"${nameof(Build.Revision)}")
})
}).ToListAsync();
return grouping.Count;
}
public async Task<List<BuildModel>> SelectGroup(BuildGroup group, int limit = -1, int skip = 0)
public async Task<List<Build>> SelectGroup(BuildGroup group, int limit = -1, int skip = 0)
{
IFindFluent<BuildModel, BuildModel> query = _buildCollection.Find(new BsonDocument
IFindFluent<Build, Build> query = _buildCollection.Find(new BsonDocument
{
new BsonElement(nameof(BuildModel.MajorVersion), group.Major),
new BsonElement(nameof(BuildModel.MinorVersion), group.Minor),
new BsonElement(nameof(BuildModel.Number), group.Build),
new BsonElement(nameof(BuildModel.Revision), group.Revision)
new BsonElement(nameof(Build.MajorVersion), group.Major),
new BsonElement(nameof(Build.MinorVersion), group.Minor),
new BsonElement(nameof(Build.Number), group.Build),
new BsonElement(nameof(Build.Revision), group.Revision)
}).Sort(new BsonDocument
{
new BsonElement(nameof(BuildModel.BuildTime), 1)
new BsonElement(nameof(Build.BuildTime), 1)
}).Skip(skip);
if (limit > 0)
@ -92,10 +92,10 @@ namespace BuildFeed.Model
public async Task<long> SelectGroupCount(BuildGroup group) => await _buildCollection.CountAsync(new BsonDocument
{
new BsonElement(nameof(BuildModel.MajorVersion), @group.Major),
new BsonElement(nameof(BuildModel.MinorVersion), @group.Minor),
new BsonElement(nameof(BuildModel.Number), @group.Build),
new BsonElement(nameof(BuildModel.Revision), @group.Revision)
new BsonElement(nameof(Build.MajorVersion), @group.Major),
new BsonElement(nameof(Build.MinorVersion), @group.Minor),
new BsonElement(nameof(Build.Number), @group.Build),
new BsonElement(nameof(Build.Revision), @group.Revision)
});
}
}

View File

@ -7,11 +7,11 @@ using MongoDB.Driver;
namespace BuildFeed.Model
{
public partial class Build
public partial class BuildRepository
{
public async Task<string[]> SelectAllLabs(int limit = -1, int skip = 0)
{
IAggregateFluent<BsonDocument> query = _buildCollection.Aggregate().Group(new BsonDocument("_id", $"${nameof(BuildModel.Lab)}")).Sort(new BsonDocument("_id", 1)).Skip(skip);
IAggregateFluent<BsonDocument> query = _buildCollection.Aggregate().Group(new BsonDocument("_id", $"${nameof(Build.Lab)}")).Sort(new BsonDocument("_id", 1)).Skip(skip);
if (limit > 0)
{
@ -29,9 +29,9 @@ namespace BuildFeed.Model
{
IAggregateFluent<BsonDocument> query = _buildCollection.Aggregate().Match(new BsonDocument
{
new BsonElement(nameof(BuildModel.MajorVersion), major),
new BsonElement(nameof(BuildModel.MinorVersion), minor)
}).Group(new BsonDocument("_id", $"${nameof(BuildModel.Lab)}")).Sort(new BsonDocument("_id", 1));
new BsonElement(nameof(Build.MajorVersion), major),
new BsonElement(nameof(Build.MinorVersion), minor)
}).Group(new BsonDocument("_id", $"${nameof(Build.Lab)}")).Sort(new BsonDocument("_id", 1));
List<BsonDocument> grouping = await query.ToListAsync();
@ -52,16 +52,16 @@ namespace BuildFeed.Model
public async Task<long> SelectAllLabsCount()
{
IAggregateFluent<BsonDocument> query = _buildCollection.Aggregate().Group(new BsonDocument("_id", new BsonDocument(nameof(BuildModel.Lab), $"${nameof(BuildModel.Lab)}"))).Sort(new BsonDocument("_id", 1));
IAggregateFluent<BsonDocument> query = _buildCollection.Aggregate().Group(new BsonDocument("_id", new BsonDocument(nameof(Build.Lab), $"${nameof(Build.Lab)}"))).Sort(new BsonDocument("_id", 1));
List<BsonDocument> grouping = await query.ToListAsync();
return grouping.Count;
}
public async Task<List<BuildModel>> SelectLab(string lab, int limit = -1, int skip = 0)
public async Task<List<Build>> SelectLab(string lab, int limit = -1, int skip = 0)
{
IFindFluent<BuildModel, BuildModel> query = _buildCollection.Find(new BsonDocument(nameof(BuildModel.LabUrl), lab)).Sort(sortByCompileDate).Skip(skip);
IFindFluent<Build, Build> query = _buildCollection.Find(new BsonDocument(nameof(Build.LabUrl), lab)).Sort(sortByCompileDate).Skip(skip);
if (limit > 0)
{
@ -71,6 +71,6 @@ namespace BuildFeed.Model
return await query.ToListAsync();
}
public async Task<long> SelectLabCount(string lab) => await _buildCollection.CountAsync(new BsonDocument(nameof(BuildModel.LabUrl), lab));
public async Task<long> SelectLabCount(string lab) => await _buildCollection.CountAsync(new BsonDocument(nameof(Build.LabUrl), lab));
}
}

View File

@ -6,15 +6,15 @@ using MongoDB.Driver;
namespace BuildFeed.Model
{
public partial class Build
public partial class BuildRepository
{
public Task<TypeOfSource[]> SelectAllSources(int limit = -1, int skip = 0) => Task.Run(() => Enum.GetValues(typeof(TypeOfSource)) as TypeOfSource[]);
public Task<long> SelectAllSourcesCount() => Task.Run(() => Enum.GetValues(typeof(TypeOfSource)).LongLength);
public async Task<List<BuildModel>> SelectSource(TypeOfSource source, int limit = -1, int skip = 0)
public async Task<List<Build>> SelectSource(TypeOfSource source, int limit = -1, int skip = 0)
{
IFindFluent<BuildModel, BuildModel> query = _buildCollection.Find(new BsonDocument(nameof(BuildModel.SourceType), source)).Sort(sortByOrder).Skip(skip);
IFindFluent<Build, Build> query = _buildCollection.Find(new BsonDocument(nameof(Build.SourceType), source)).Sort(sortByOrder).Skip(skip);
if (limit > 0)
{
@ -24,6 +24,6 @@ namespace BuildFeed.Model
return await query.ToListAsync();
}
public async Task<long> SelectSourceCount(TypeOfSource source) => await _buildCollection.CountAsync(new BsonDocument(nameof(BuildModel.SourceType), source));
public async Task<long> SelectSourceCount(TypeOfSource source) => await _buildCollection.CountAsync(new BsonDocument(nameof(Build.SourceType), source));
}
}

View File

@ -6,15 +6,15 @@ using MongoDB.Driver;
namespace BuildFeed.Model
{
public partial class Build
public partial class BuildRepository
{
public async Task<BuildVersion[]> SelectAllVersions(int limit = -1, int skip = 0)
{
IAggregateFluent<BsonDocument> query = _buildCollection.Aggregate().Group(new BsonDocument("_id",
new BsonDocument
{
new BsonElement(nameof(BuildVersion.Major), $"${nameof(BuildModel.MajorVersion)}"),
new BsonElement(nameof(BuildVersion.Minor), $"${nameof(BuildModel.MinorVersion)}")
new BsonElement(nameof(BuildVersion.Major), $"${nameof(Build.MajorVersion)}"),
new BsonElement(nameof(BuildVersion.Minor), $"${nameof(Build.MinorVersion)}")
})).Sort(new BsonDocument
{
new BsonElement($"_id.{nameof(BuildVersion.Major)}", -1),
@ -41,18 +41,18 @@ namespace BuildFeed.Model
List<BsonDocument> query = await _buildCollection.Aggregate().Group(new BsonDocument("_id",
new BsonDocument
{
new BsonElement(nameof(BuildVersion.Major), $"${nameof(BuildModel.MajorVersion)}"),
new BsonElement(nameof(BuildVersion.Minor), $"${nameof(BuildModel.MinorVersion)}")
new BsonElement(nameof(BuildVersion.Major), $"${nameof(Build.MajorVersion)}"),
new BsonElement(nameof(BuildVersion.Minor), $"${nameof(Build.MinorVersion)}")
})).ToListAsync();
return query.Count;
}
public async Task<List<BuildModel>> SelectVersion(uint major, uint minor, int limit = -1, int skip = 0)
public async Task<List<Build>> SelectVersion(uint major, uint minor, int limit = -1, int skip = 0)
{
IFindFluent<BuildModel, BuildModel> query = _buildCollection.Find(new BsonDocument
IFindFluent<Build, Build> query = _buildCollection.Find(new BsonDocument
{
new BsonElement(nameof(BuildModel.MajorVersion), major),
new BsonElement(nameof(BuildModel.MinorVersion), minor)
new BsonElement(nameof(Build.MajorVersion), major),
new BsonElement(nameof(Build.MinorVersion), minor)
}).Sort(sortByOrder).Skip(skip);
if (limit > 0)
@ -65,8 +65,8 @@ namespace BuildFeed.Model
public async Task<long> SelectVersionCount(uint major, uint minor) => await _buildCollection.CountAsync(new BsonDocument
{
new BsonElement(nameof(BuildModel.MajorVersion), major),
new BsonElement(nameof(BuildModel.MinorVersion), minor)
new BsonElement(nameof(Build.MajorVersion), major),
new BsonElement(nameof(Build.MinorVersion), minor)
});
}
}

View File

@ -7,14 +7,14 @@ using MongoDB.Driver;
namespace BuildFeed.Model
{
public partial class Build
public partial class BuildRepository
{
public async Task<int[]> SelectAllYears(int limit = -1, int skip = 0)
{
IAggregateFluent<BsonDocument> query =
_buildCollection.Aggregate()
.Match(Builders<BuildModel>.Filter.Ne(b => b.BuildTime, null))
.Group(new BsonDocument("_id", new BsonDocument("$year", $"${nameof(BuildModel.BuildTime)}")))
.Match(Builders<Build>.Filter.Ne(b => b.BuildTime, null))
.Group(new BsonDocument("_id", new BsonDocument("$year", $"${nameof(Build.BuildTime)}")))
.Sort(new BsonDocument("_id", -1))
.Skip(skip);
@ -32,16 +32,16 @@ namespace BuildFeed.Model
public async Task<long> SelectAllYearsCount()
{
List<BsonDocument> query = await _buildCollection.Aggregate().Match(Builders<BuildModel>.Filter.Ne(b => b.BuildTime, null)).Group(new BsonDocument("_id", new BsonDocument("$year", $"${nameof(BuildModel.BuildTime)}"))).ToListAsync();
List<BsonDocument> query = await _buildCollection.Aggregate().Match(Builders<Build>.Filter.Ne(b => b.BuildTime, null)).Group(new BsonDocument("_id", new BsonDocument("$year", $"${nameof(Build.BuildTime)}"))).ToListAsync();
return query.Count;
}
public async Task<List<BuildModel>> SelectYear(int year, int limit = -1, int skip = 0)
public async Task<List<Build>> SelectYear(int year, int limit = -1, int skip = 0)
{
IFindFluent<BuildModel, BuildModel> query =
_buildCollection.Find(Builders<BuildModel>.Filter.And(Builders<BuildModel>.Filter.Gte(b => b.BuildTime, new DateTime(year, 1, 1, 0, 0, 0, DateTimeKind.Utc)),
Builders<BuildModel>.Filter.Lte(b => b.BuildTime, new DateTime(year, 12, 31, 23, 59, 59, DateTimeKind.Utc)))).Sort(sortByCompileDate).Skip(skip);
IFindFluent<Build, Build> query =
_buildCollection.Find(Builders<Build>.Filter.And(Builders<Build>.Filter.Gte(b => b.BuildTime, new DateTime(year, 1, 1, 0, 0, 0, DateTimeKind.Utc)),
Builders<Build>.Filter.Lte(b => b.BuildTime, new DateTime(year, 12, 31, 23, 59, 59, DateTimeKind.Utc)))).Sort(sortByCompileDate).Skip(skip);
if (limit > 0)
{
@ -54,7 +54,7 @@ namespace BuildFeed.Model
public async Task<long> SelectYearCount(int year)
=>
await
_buildCollection.CountAsync(Builders<BuildModel>.Filter.And(Builders<BuildModel>.Filter.Gte(b => b.BuildTime, new DateTime(year, 1, 1, 0, 0, 0, DateTimeKind.Utc)),
Builders<BuildModel>.Filter.Lte(b => b.BuildTime, new DateTime(year, 12, 31, 23, 59, 59, DateTimeKind.Utc))));
_buildCollection.CountAsync(Builders<Build>.Filter.And(Builders<Build>.Filter.Gte(b => b.BuildTime, new DateTime(year, 1, 1, 0, 0, 0, DateTimeKind.Utc)),
Builders<Build>.Filter.Lte(b => b.BuildTime, new DateTime(year, 12, 31, 23, 59, 59, DateTimeKind.Utc))));
}
}

View File

@ -1,249 +1,187 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Linq;
using System.Threading.Tasks;
using BuildFeed.Model.View;
using MongoDB.Bson;
using MongoDB.Driver;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Text;
using System.Web.Mvc;
using BuildFeed.Local;
using HtmlAgilityPack;
using MongoDB.Bson.Serialization.Attributes;
using Required = System.ComponentModel.DataAnnotations.RequiredAttribute;
namespace BuildFeed.Model
{
public partial class Build
[DataObject, BsonIgnoreExtraElements]
public class Build
{
private const string BUILD_COLLECTION_NAME = "builds";
private static readonly BsonDocument sortByAddedDate = new BsonDocument(nameof(BuildModel.Added), -1);
private static readonly BsonDocument sortByCompileDate = new BsonDocument(nameof(BuildModel.BuildTime), -1);
private static readonly BsonDocument sortByLeakedDate = new BsonDocument(nameof(BuildModel.LeakDate), -1);
[Key, BsonId]
public Guid Id { get; set; }
private static readonly BsonDocument sortByOrder = new BsonDocument
public long? LegacyId { get; set; }
[@Required]
[Display(ResourceType = typeof(VariantTerms), Name = nameof(VariantTerms.Model_MajorVersion))]
public uint MajorVersion { get; set; }
[@Required]
[Display(ResourceType = typeof(VariantTerms), Name = nameof(VariantTerms.Model_MinorVersion))]
public uint MinorVersion { get; set; }
[@Required]
[Display(ResourceType = typeof(VariantTerms), Name = nameof(VariantTerms.Model_BuildNumber))]
public uint Number { get; set; }
[Display(ResourceType = typeof(VariantTerms), Name = nameof(VariantTerms.Model_Revision))]
[DisplayFormat(ConvertEmptyStringToNull = true)]
public uint? Revision { get; set; }
[Display(ResourceType = typeof(VariantTerms), Name = nameof(VariantTerms.Model_LabString))]
public string Lab { get; set; }
[Display(ResourceType = typeof(VariantTerms), Name = nameof(VariantTerms.Model_BuildTime))]
[DisplayFormat(ConvertEmptyStringToNull = true, ApplyFormatInEditMode = true, DataFormatString = "{0:yyMMdd-HHmm}")]
public DateTime? BuildTime { get; set; }
[@Required]
[Display(ResourceType = typeof(VariantTerms), Name = nameof(VariantTerms.Model_Added))]
public DateTime Added { get; set; }
[@Required]
[Display(ResourceType = typeof(VariantTerms), Name = nameof(VariantTerms.Model_Modified))]
public DateTime Modified { get; set; }
[@Required]
[Display(ResourceType = typeof(VariantTerms), Name = nameof(VariantTerms.Model_SourceType))]
[EnumDataType(typeof(TypeOfSource))]
public TypeOfSource SourceType { get; set; }
[Display(ResourceType = typeof(VariantTerms), Name = nameof(VariantTerms.Model_SourceDetails))]
[AllowHtml]
public string SourceDetails { get; set; }
[Display(ResourceType = typeof(VariantTerms), Name = nameof(VariantTerms.Model_LeakDate))]
[DisplayFormat(ConvertEmptyStringToNull = true, ApplyFormatInEditMode = true)]
public DateTime? LeakDate { get; set; }
public string LabUrl { get; set; }
public bool IsLeaked => SourceType == TypeOfSource.PublicRelease || SourceType == TypeOfSource.InternalLeak || SourceType == TypeOfSource.UpdateGDR || SourceType == TypeOfSource.UpdateLDR;
public string FullBuildString
{
new BsonElement(nameof(BuildModel.MajorVersion), -1),
new BsonElement(nameof(BuildModel.MinorVersion), -1),
new BsonElement(nameof(BuildModel.Number), -1),
new BsonElement(nameof(BuildModel.Revision), -1),
new BsonElement(nameof(BuildModel.BuildTime), -1)
};
private readonly IMongoCollection<BuildModel> _buildCollection;
private readonly IMongoDatabase _buildDatabase;
private readonly MongoClient _dbClient;
public Build()
{
_dbClient = new MongoClient(new MongoClientSettings
get
{
Server = new MongoServerAddress(MongoConfig.Host, MongoConfig.Port)
});
StringBuilder sb = new StringBuilder();
sb.Append($"{MajorVersion}.{MinorVersion}.{Number}");
_buildDatabase = _dbClient.GetDatabase(MongoConfig.Database);
_buildCollection = _buildDatabase.GetCollection<BuildModel>(BUILD_COLLECTION_NAME);
}
public async Task SetupIndexes()
{
List<BsonDocument> indexes = await (await _buildCollection.Indexes.ListAsync()).ToListAsync();
if (indexes.All(i => i["name"] != "_idx_group"))
{
await
_buildCollection.Indexes.CreateOneAsync(
Builders<BuildModel>.IndexKeys.Combine(Builders<BuildModel>.IndexKeys.Descending(b => b.MajorVersion),
Builders<BuildModel>.IndexKeys.Descending(b => b.MinorVersion),
Builders<BuildModel>.IndexKeys.Descending(b => b.Number),
Builders<BuildModel>.IndexKeys.Descending(b => b.Revision)),
new CreateIndexOptions
{
Name = "_idx_group"
});
}
if (indexes.All(i => i["name"] != "_idx_legacy"))
{
await _buildCollection.Indexes.CreateOneAsync(Builders<BuildModel>.IndexKeys.Ascending(b => b.LegacyId),
new CreateIndexOptions
{
Name = "_idx_legacy"
});
}
if (indexes.All(i => i["name"] != "_idx_lab"))
{
await _buildCollection.Indexes.CreateOneAsync(Builders<BuildModel>.IndexKeys.Ascending(b => b.Lab),
new CreateIndexOptions
{
Name = "_idx_lab"
});
}
}
[DataObjectMethod(DataObjectMethodType.Select, true)]
public async Task<List<BuildModel>> Select() => await _buildCollection.Find(new BsonDocument()).ToListAsync();
[DataObjectMethod(DataObjectMethodType.Select, false)]
public async Task<BuildModel> SelectById(Guid id) => await _buildCollection.Find(Builders<BuildModel>.Filter.Eq(b => b.Id, id)).SingleOrDefaultAsync();
[DataObjectMethod(DataObjectMethodType.Select, false)]
public async Task<BuildModel> SelectByLegacyId(long id) => await _buildCollection.Find(Builders<BuildModel>.Filter.Eq(b => b.LegacyId, id)).SingleOrDefaultAsync();
[DataObjectMethod(DataObjectMethodType.Select, false)]
public async Task<List<BuildModel>> SelectBuildsByOrder(int limit = -1, int skip = 0)
{
IFindFluent<BuildModel, BuildModel> query = _buildCollection.Find(new BsonDocument()).Sort(sortByOrder).Skip(skip);
if (limit > 0)
{
query = query.Limit(limit);
}
return await query.ToListAsync();
}
[DataObjectMethod(DataObjectMethodType.Select, false)]
public async Task<FrontPage> SelectFrontPage()
{
FrontPage fp = new FrontPage();
IFindFluent<BuildModel, BuildModel> query = _buildCollection.Find(new BsonDocument
{
if (Revision.HasValue)
{
nameof(BuildModel.LabUrl), new BsonDocument
{
{ "$in", new BsonArray(ConfigurationManager.AppSettings["site:OSGLab"].Split(';')) }
}
sb.Append($".{Revision}");
}
}).Sort(sortByCompileDate).Limit(1);
fp.CurrentCanary = await query.FirstOrDefaultAsync();
query = _buildCollection.Find(new BsonDocument
{
if (!string.IsNullOrWhiteSpace(Lab))
{
nameof(BuildModel.LabUrl), new BsonDocument
{
{ "$in", new BsonArray(ConfigurationManager.AppSettings["site:InsiderLab"].Split(';')) }
}
},
{
nameof(BuildModel.SourceType), new BsonDocument
{
{
"$in", new BsonArray
{
TypeOfSource.PublicRelease,
TypeOfSource.UpdateGDR
}
}
}
sb.Append($".{Lab}");
}
}).Sort(sortByCompileDate).Limit(1);
fp.CurrentInsider = await query.FirstOrDefaultAsync();
query = _buildCollection.Find(new BsonDocument
{
if (BuildTime.HasValue)
{
nameof(BuildModel.LabUrl), new BsonDocument
{
{ "$in", new BsonArray(ConfigurationManager.AppSettings["site:ReleaseLab"].Split(';')) }
}
},
{
nameof(BuildModel.SourceType), new BsonDocument
{
{
"$in", new BsonArray
{
TypeOfSource.PublicRelease,
TypeOfSource.UpdateGDR
}
}
}
sb.Append($".{BuildTime.Value.ToString("yyMMdd-HHmm", CultureInfo.InvariantCulture.DateTimeFormat)}");
}
}).Sort(sortByCompileDate).Limit(1);
fp.CurrentRelease = await query.FirstOrDefaultAsync();
return fp;
}
[DataObjectMethod(DataObjectMethodType.Select, false)]
public async Task<List<BuildModel>> SelectBuildsByCompileDate(int limit = -1, int skip = 0)
{
IFindFluent<BuildModel, BuildModel> query = _buildCollection.Find(new BsonDocument()).Sort(sortByCompileDate).Skip(skip);
if (limit > 0)
{
query = query.Limit(limit);
return sb.ToString();
}
return await query.ToListAsync();
}
[DataObjectMethod(DataObjectMethodType.Select, false)]
public async Task<List<BuildModel>> SelectBuildsByAddedDate(int limit = -1, int skip = 0)
public ProjectFamily Family
{
IFindFluent<BuildModel, BuildModel> query = _buildCollection.Find(new BsonDocument()).Sort(sortByAddedDate).Skip(skip);
if (limit > 0)
get
{
query = query.Limit(limit);
if (Number >= 14800)
{
return ProjectFamily.Redstone2;
}
if (Number >= 11000)
{
return ProjectFamily.Redstone;
}
if (Number >= 10500)
{
return ProjectFamily.Threshold2;
}
if (Number >= 9700)
{
return ProjectFamily.Threshold;
}
if (Number >= 9250)
{
return ProjectFamily.Windows81;
}
if (Number >= 7650)
{
return ProjectFamily.Windows8;
}
if (Number >= 6020)
{
return ProjectFamily.Windows7;
}
if (MajorVersion == 6
&& Number >= 5000)
{
return ProjectFamily.WindowsVista;
}
if (MajorVersion == 6)
{
return ProjectFamily.Longhorn;
}
if (MajorVersion == 5
&& Number >= 3000)
{
return ProjectFamily.Server2003;
}
if (MajorVersion == 5
&& Number >= 2205)
{
return ProjectFamily.WindowsXP;
}
if (MajorVersion == 5
&& MinorVersion == 50)
{
return ProjectFamily.Neptune;
}
if (MajorVersion == 5)
{
return ProjectFamily.Windows2000;
}
return ProjectFamily.None;
}
return await query.ToListAsync();
}
[DataObjectMethod(DataObjectMethodType.Select, false)]
public async Task<List<BuildModel>> SelectBuildsByLeakedDate(int limit = -1, int skip = 0)
public string SourceDetailsFiltered
{
IFindFluent<BuildModel, BuildModel> query = _buildCollection.Find(new BsonDocument()).Sort(sortByLeakedDate).Skip(skip);
if (limit > 0)
get
{
query = query.Limit(limit);
HtmlDocument hDoc = new HtmlDocument();
hDoc.LoadHtml($"<div>{SourceDetails}</div>");
if (string.IsNullOrWhiteSpace(hDoc.DocumentNode.InnerText))
{
return "";
}
if (Uri.IsWellFormedUriString(hDoc.DocumentNode.InnerText, UriKind.Absolute))
{
Uri uri = new Uri(hDoc.DocumentNode.InnerText, UriKind.Absolute);
return $"<a href=\"{uri}\" target=\"_blank\">{VariantTerms.Model_ExternalLink} <i class=\"fa fa-external-link\"></i></a>";
}
return SourceDetails;
}
return await query.ToListAsync();
}
[DataObjectMethod(DataObjectMethodType.Insert, true)]
public async Task Insert(BuildModel item)
{
item.Id = Guid.NewGuid();
item.LabUrl = item.GenerateLabUrl();
await _buildCollection.InsertOneAsync(item);
}
[DataObjectMethod(DataObjectMethodType.Insert, false)]
public async Task InsertAll(IEnumerable<BuildModel> items)
{
List<BuildModel> generatedItems = new List<BuildModel>();
foreach (BuildModel item in items)
{
item.Id = Guid.NewGuid();
item.LabUrl = item.GenerateLabUrl();
generatedItems.Add(item);
}
await _buildCollection.InsertManyAsync(generatedItems);
}
[DataObjectMethod(DataObjectMethodType.Update, true)]
public async Task Update(BuildModel item)
{
BuildModel old = await SelectById(item.Id);
item.Added = old.Added;
item.Modified = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Utc);
item.LabUrl = item.GenerateLabUrl();
await _buildCollection.ReplaceOneAsync(Builders<BuildModel>.Filter.Eq(b => b.Id, item.Id), item);
}
[DataObjectMethod(DataObjectMethodType.Delete, true)]
public async Task DeleteById(Guid id)
{
await _buildCollection.DeleteOneAsync(Builders<BuildModel>.Filter.Eq(b => b.Id, id));
}
public string GenerateLabUrl() => !string.IsNullOrEmpty(Lab)
? Lab.Replace('/', '-').ToLower()
: "";
}
}

View File

@ -95,9 +95,9 @@
<Compile Include="Build-Source.cs" />
<Compile Include="Build-Version.cs" />
<Compile Include="Build-Year.cs" />
<Compile Include="Build.cs" />
<Compile Include="BuildRepository.cs" />
<Compile Include="BuildGroup.cs" />
<Compile Include="BuildModel.cs" />
<Compile Include="Build.cs" />
<Compile Include="BuildVersion.cs" />
<Compile Include="MetaItem.cs" />
<Compile Include="MongoConfig.cs" />

View File

@ -1,197 +0,0 @@
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Text;
using System.Web.Mvc;
using BuildFeed.Local;
using HtmlAgilityPack;
using MongoDB.Bson.Serialization.Attributes;
using Required = System.ComponentModel.DataAnnotations.RequiredAttribute;
namespace BuildFeed.Model
{
[DataObject, BsonIgnoreExtraElements]
public class BuildModel
{
[Key, BsonId]
public Guid Id { get; set; }
public long? LegacyId { get; set; }
[@Required]
[Display(ResourceType = typeof(VariantTerms), Name = nameof(VariantTerms.Model_MajorVersion))]
public uint MajorVersion { get; set; }
[@Required]
[Display(ResourceType = typeof(VariantTerms), Name = nameof(VariantTerms.Model_MinorVersion))]
public uint MinorVersion { get; set; }
[@Required]
[Display(ResourceType = typeof(VariantTerms), Name = nameof(VariantTerms.Model_BuildNumber))]
public uint Number { get; set; }
[Display(ResourceType = typeof(VariantTerms), Name = nameof(VariantTerms.Model_Revision))]
[DisplayFormat(ConvertEmptyStringToNull = true)]
public uint? Revision { get; set; }
[Display(ResourceType = typeof(VariantTerms), Name = nameof(VariantTerms.Model_LabString))]
public string Lab { get; set; }
[Display(ResourceType = typeof(VariantTerms), Name = nameof(VariantTerms.Model_BuildTime))]
[DisplayFormat(ConvertEmptyStringToNull = true, ApplyFormatInEditMode = true, DataFormatString = "{0:yyMMdd-HHmm}")]
public DateTime? BuildTime { get; set; }
[@Required]
[Display(ResourceType = typeof(VariantTerms), Name = nameof(VariantTerms.Model_Added))]
public DateTime Added { get; set; }
[@Required]
[Display(ResourceType = typeof(VariantTerms), Name = nameof(VariantTerms.Model_Modified))]
public DateTime Modified { get; set; }
[@Required]
[Display(ResourceType = typeof(VariantTerms), Name = nameof(VariantTerms.Model_SourceType))]
[EnumDataType(typeof(TypeOfSource))]
public TypeOfSource SourceType { get; set; }
[Display(ResourceType = typeof(VariantTerms), Name = nameof(VariantTerms.Model_SourceDetails))]
[AllowHtml]
public string SourceDetails { get; set; }
[Display(ResourceType = typeof(VariantTerms), Name = nameof(VariantTerms.Model_LeakDate))]
[DisplayFormat(ConvertEmptyStringToNull = true, ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}")]
public DateTime? LeakDate { get; set; }
public string LabUrl { get; set; }
public bool IsLeaked
{
get
{
switch (SourceType)
{
case TypeOfSource.PublicRelease:
case TypeOfSource.InternalLeak:
case TypeOfSource.UpdateGDR:
case TypeOfSource.UpdateLDR:
return true;
default:
return false;
}
}
}
public string FullBuildString
{
get
{
StringBuilder sb = new StringBuilder();
sb.Append($"{MajorVersion}.{MinorVersion}.{Number}");
if (Revision.HasValue)
{
sb.Append($".{Revision}");
}
if (!string.IsNullOrWhiteSpace(Lab))
{
sb.Append($".{Lab}");
}
if (BuildTime.HasValue)
{
sb.Append($".{BuildTime.Value.ToString("yyMMdd-HHmm", CultureInfo.InvariantCulture.DateTimeFormat)}");
}
return sb.ToString();
}
}
public ProjectFamily Family
{
get
{
if (Number >= 14800)
{
return ProjectFamily.Redstone2;
}
if (Number >= 11000)
{
return ProjectFamily.Redstone;
}
if (Number >= 10500)
{
return ProjectFamily.Threshold2;
}
if (Number >= 9700)
{
return ProjectFamily.Threshold;
}
if (Number >= 9250)
{
return ProjectFamily.Windows81;
}
if (Number >= 7650)
{
return ProjectFamily.Windows8;
}
if (Number >= 6020)
{
return ProjectFamily.Windows7;
}
if (MajorVersion == 6
&& Number >= 5000)
{
return ProjectFamily.WindowsVista;
}
if (MajorVersion == 6)
{
return ProjectFamily.Longhorn;
}
if (MajorVersion == 5
&& Number >= 3000)
{
return ProjectFamily.Server2003;
}
if (MajorVersion == 5
&& Number >= 2205)
{
return ProjectFamily.WindowsXP;
}
if (MajorVersion == 5
&& MinorVersion == 50)
{
return ProjectFamily.Neptune;
}
if (MajorVersion == 5)
{
return ProjectFamily.Windows2000;
}
return ProjectFamily.None;
}
}
public string SourceDetailsFiltered
{
get
{
HtmlDocument hDoc = new HtmlDocument();
hDoc.LoadHtml($"<div>{SourceDetails}</div>");
if (string.IsNullOrWhiteSpace(hDoc.DocumentNode.InnerText))
{
return "";
}
if (Uri.IsWellFormedUriString(hDoc.DocumentNode.InnerText, UriKind.Absolute))
{
Uri uri = new Uri(hDoc.DocumentNode.InnerText, UriKind.Absolute);
return $"<a href=\"{uri}\" target=\"_blank\">{VariantTerms.Model_ExternalLink} <i class=\"fa fa-external-link\"></i></a>";
}
return SourceDetails;
}
}
public string GenerateLabUrl() => (Lab ?? "").Replace('/', '-').ToLower();
}
}

View File

@ -0,0 +1,254 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Linq;
using System.Threading.Tasks;
using BuildFeed.Model.View;
using MongoDB.Bson;
using MongoDB.Driver;
namespace BuildFeed.Model
{
public partial class BuildRepository
{
private const string BUILD_COLLECTION_NAME = "builds";
private static readonly BsonDocument sortByAddedDate = new BsonDocument(nameof(Build.Added), -1);
private static readonly BsonDocument sortByCompileDate = new BsonDocument(nameof(Build.BuildTime), -1);
private static readonly BsonDocument sortByLeakedDate = new BsonDocument(nameof(Build.LeakDate), -1);
private static readonly BsonDocument sortByOrder = new BsonDocument
{
new BsonElement(nameof(Build.MajorVersion), -1),
new BsonElement(nameof(Build.MinorVersion), -1),
new BsonElement(nameof(Build.Number), -1),
new BsonElement(nameof(Build.Revision), -1),
new BsonElement(nameof(Build.BuildTime), -1)
};
private readonly IMongoCollection<Build> _buildCollection;
public BuildRepository()
{
MongoClient dbClient = new MongoClient(new MongoClientSettings
{
Server = new MongoServerAddress(MongoConfig.Host, MongoConfig.Port)
});
IMongoDatabase buildDatabase = dbClient.GetDatabase(MongoConfig.Database);
_buildCollection = buildDatabase.GetCollection<Build>(BUILD_COLLECTION_NAME);
}
public async Task SetupIndexes()
{
List<BsonDocument> indexes = await (await _buildCollection.Indexes.ListAsync()).ToListAsync();
if (indexes.All(i => i["name"] != "_idx_group"))
{
await
_buildCollection.Indexes.CreateOneAsync(
Builders<Build>.IndexKeys.Combine(Builders<Build>.IndexKeys.Descending(b => b.MajorVersion),
Builders<Build>.IndexKeys.Descending(b => b.MinorVersion),
Builders<Build>.IndexKeys.Descending(b => b.Number),
Builders<Build>.IndexKeys.Descending(b => b.Revision)),
new CreateIndexOptions
{
Name = "_idx_group"
});
}
if (indexes.All(i => i["name"] != "_idx_legacy"))
{
await _buildCollection.Indexes.CreateOneAsync(Builders<Build>.IndexKeys.Ascending(b => b.LegacyId),
new CreateIndexOptions
{
Name = "_idx_legacy"
});
}
if (indexes.All(i => i["name"] != "_idx_lab"))
{
await _buildCollection.Indexes.CreateOneAsync(Builders<Build>.IndexKeys.Ascending(b => b.Lab),
new CreateIndexOptions
{
Name = "_idx_lab"
});
}
if (indexes.All(i => i["name"] != "_idx_date"))
{
await _buildCollection.Indexes.CreateOneAsync(Builders<Build>.IndexKeys.Descending(b => b.BuildTime),
new CreateIndexOptions
{
Name = "_idx_date"
});
}
}
[DataObjectMethod(DataObjectMethodType.Select, true)]
public async Task<List<Build>> Select() => await _buildCollection.Find(new BsonDocument()).ToListAsync();
[DataObjectMethod(DataObjectMethodType.Select, false)]
public async Task<Build> SelectById(Guid id) => await _buildCollection.Find(Builders<Build>.Filter.Eq(b => b.Id, id)).SingleOrDefaultAsync();
[DataObjectMethod(DataObjectMethodType.Select, false)]
public async Task<Build> SelectByLegacyId(long id) => await _buildCollection.Find(Builders<Build>.Filter.Eq(b => b.LegacyId, id)).SingleOrDefaultAsync();
[DataObjectMethod(DataObjectMethodType.Select, false)]
public async Task<List<Build>> SelectBuildsByOrder(int limit = -1, int skip = 0)
{
IFindFluent<Build, Build> query = _buildCollection.Find(new BsonDocument()).Sort(sortByOrder).Skip(skip);
if (limit > 0)
{
query = query.Limit(limit);
}
return await query.ToListAsync();
}
[DataObjectMethod(DataObjectMethodType.Select, false)]
public async Task<FrontPage> SelectFrontPage()
{
FrontPage fp = new FrontPage();
IFindFluent<Build, Build> query = _buildCollection.Find(new BsonDocument
{
{
nameof(Build.LabUrl), new BsonDocument
{
{ "$in", new BsonArray(ConfigurationManager.AppSettings["site:OSGLab"].Split(';')) }
}
}
}).Sort(sortByCompileDate).Limit(1);
fp.CurrentCanary = await query.FirstOrDefaultAsync();
query = _buildCollection.Find(new BsonDocument
{
{
nameof(Build.LabUrl), new BsonDocument
{
{ "$in", new BsonArray(ConfigurationManager.AppSettings["site:InsiderLab"].Split(';')) }
}
},
{
nameof(Build.SourceType), new BsonDocument
{
{
"$in", new BsonArray
{
TypeOfSource.PublicRelease,
TypeOfSource.UpdateGDR
}
}
}
}
}).Sort(sortByCompileDate).Limit(1);
fp.CurrentInsider = await query.FirstOrDefaultAsync();
query = _buildCollection.Find(new BsonDocument
{
{
nameof(Build.LabUrl), new BsonDocument
{
{ "$in", new BsonArray(ConfigurationManager.AppSettings["site:ReleaseLab"].Split(';')) }
}
},
{
nameof(Build.SourceType), new BsonDocument
{
{
"$in", new BsonArray
{
TypeOfSource.PublicRelease,
TypeOfSource.UpdateGDR
}
}
}
}
}).Sort(sortByCompileDate).Limit(1);
fp.CurrentRelease = await query.FirstOrDefaultAsync();
return fp;
}
[DataObjectMethod(DataObjectMethodType.Select, false)]
public async Task<List<Build>> SelectBuildsByCompileDate(int limit = -1, int skip = 0)
{
IFindFluent<Build, Build> query = _buildCollection.Find(new BsonDocument()).Sort(sortByCompileDate).Skip(skip);
if (limit > 0)
{
query = query.Limit(limit);
}
return await query.ToListAsync();
}
[DataObjectMethod(DataObjectMethodType.Select, false)]
public async Task<List<Build>> SelectBuildsByAddedDate(int limit = -1, int skip = 0)
{
IFindFluent<Build, Build> query = _buildCollection.Find(new BsonDocument()).Sort(sortByAddedDate).Skip(skip);
if (limit > 0)
{
query = query.Limit(limit);
}
return await query.ToListAsync();
}
[DataObjectMethod(DataObjectMethodType.Select, false)]
public async Task<List<Build>> SelectBuildsByLeakedDate(int limit = -1, int skip = 0)
{
IFindFluent<Build, Build> query = _buildCollection.Find(new BsonDocument()).Sort(sortByLeakedDate).Skip(skip);
if (limit > 0)
{
query = query.Limit(limit);
}
return await query.ToListAsync();
}
[DataObjectMethod(DataObjectMethodType.Insert, true)]
public async Task Insert(Build item)
{
item.Id = Guid.NewGuid();
item.LabUrl = item.GenerateLabUrl();
await _buildCollection.InsertOneAsync(item);
}
[DataObjectMethod(DataObjectMethodType.Insert, false)]
public async Task InsertAll(IEnumerable<Build> items)
{
List<Build> generatedItems = new List<Build>();
foreach (Build item in items)
{
item.Id = Guid.NewGuid();
item.LabUrl = item.GenerateLabUrl();
generatedItems.Add(item);
}
await _buildCollection.InsertManyAsync(generatedItems);
}
[DataObjectMethod(DataObjectMethodType.Update, true)]
public async Task Update(Build item)
{
Build old = await SelectById(item.Id);
item.Added = old.Added;
item.Modified = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Utc);
item.LabUrl = item.GenerateLabUrl();
await _buildCollection.ReplaceOneAsync(Builders<Build>.Filter.Eq(b => b.Id, item.Id), item);
}
[DataObjectMethod(DataObjectMethodType.Delete, true)]
public async Task DeleteById(Guid id)
{
await _buildCollection.DeleteOneAsync(Builders<Build>.Filter.Eq(b => b.Id, id));
}
}
}

View File

@ -34,7 +34,7 @@ namespace BuildFeed.Model
private readonly MongoClient _dbClient;
private readonly IMongoCollection<MetaItemModel> _metaCollection;
private readonly Build bModel;
private readonly BuildRepository bModel;
public MetaItem()
{
@ -44,7 +44,7 @@ namespace BuildFeed.Model
});
_metaCollection = _dbClient.GetDatabase(MongoConfig.Database).GetCollection<MetaItemModel>(_metaCollectionName);
bModel = new Build();
bModel = new BuildRepository();
}
[DataObjectMethod(DataObjectMethodType.Select, false)]

View File

@ -29,7 +29,7 @@ namespace BuildFeed.Model
public static void SetupIndexes()
{
Build b = new Build();
BuildRepository b = new BuildRepository();
b.SetupIndexes();
}
}

View File

@ -2,8 +2,8 @@
{
public class FrontPage
{
public BuildModel CurrentCanary { get; set; }
public BuildModel CurrentInsider { get; set; }
public BuildModel CurrentRelease { get; set; }
public Build CurrentCanary { get; set; }
public Build CurrentInsider { get; set; }
public Build CurrentRelease { get; set; }
}
}

View File

@ -14,13 +14,13 @@ namespace BuildFeed.Controllers
{
public class ApiController : System.Web.Http.ApiController
{
private readonly Build _bModel;
private readonly BuildRepository _bModel;
public ApiController() { _bModel = new Build(); }
public ApiController() { _bModel = new BuildRepository(); }
public async Task<BuildModel[]> GetBuilds(int limit = 20, int skip = 0)
public async Task<Build[]> GetBuilds(int limit = 20, int skip = 0)
{
List<BuildModel> builds = await _bModel.SelectBuildsByOrder(limit, skip);
List<Build> builds = await _bModel.SelectBuildsByOrder(limit, skip);
return builds.ToArray();
}
@ -30,9 +30,9 @@ namespace BuildFeed.Controllers
return bgroups.ToArray();
}
public async Task<BuildModel[]> GetBuildsForBuildGroup(uint major, uint minor, uint number, uint? revision = null)
public async Task<Build[]> GetBuildsForBuildGroup(uint major, uint minor, uint number, uint? revision = null)
{
List<BuildModel> builds = await _bModel.SelectGroup(new BuildGroup
List<Build> builds = await _bModel.SelectGroup(new BuildGroup
{
Major = major,
Minor = minor,
@ -43,9 +43,9 @@ namespace BuildFeed.Controllers
return builds.ToArray();
}
public async Task<BuildModel[]> GetBuildsByLab(string lab, int limit = 20, int skip = 0)
public async Task<Build[]> GetBuildsByLab(string lab, int limit = 20, int skip = 0)
{
List<BuildModel> builds = await _bModel.SelectLab(lab, limit, skip);
List<Build> builds = await _bModel.SelectLab(lab, limit, skip);
return builds.ToArray();
}
@ -67,7 +67,7 @@ namespace BuildFeed.Controllers
}
if (Membership.ValidateUser(apiModel.Username, apiModel.Password))
{
await _bModel.InsertAll(apiModel.NewBuilds.Select(nb => new BuildModel
await _bModel.InsertAll(apiModel.NewBuilds.Select(nb => new Build
{
MajorVersion = nb.MajorVersion,
MinorVersion = nb.MinorVersion,

View File

@ -18,12 +18,12 @@ namespace BuildFeed.Controllers
{
public const int PAGE_SIZE = 72;
private readonly Build _bModel;
private readonly BuildRepository _bModel;
private readonly MetaItem _mModel;
public FrontController()
{
_bModel = new Build();
_bModel = new BuildRepository();
_mModel = new MetaItem();
}
@ -71,7 +71,7 @@ namespace BuildFeed.Controllers
Revision = revision
};
List<BuildModel> builds = await _bModel.SelectGroup(bg);
List<Build> builds = await _bModel.SelectGroup(bg);
return builds.Count() == 1
? RedirectToAction(nameof(ViewBuild),
@ -79,7 +79,7 @@ namespace BuildFeed.Controllers
{
id = builds.Single().Id
}) as ActionResult
: View(new Tuple<BuildGroup, List<BuildModel>>(bg, builds));
: View(new Tuple<BuildGroup, List<Build>>(bg, builds));
}
[Route("build/{id:guid}/", Name = "Build")]
@ -88,7 +88,7 @@ namespace BuildFeed.Controllers
#endif
public async Task<ActionResult> ViewBuild(Guid id)
{
BuildModel b = await _bModel.SelectById(id);
Build b = await _bModel.SelectById(id);
if (b == null)
{
return new HttpNotFoundResult();
@ -99,7 +99,7 @@ namespace BuildFeed.Controllers
[Route("build/{id:long}/", Name = "Build (Legacy)")]
public async Task<ActionResult> ViewBuild(long id)
{
BuildModel b = await _bModel.SelectByLegacyId(id);
Build b = await _bModel.SelectByLegacyId(id);
if (b == null)
{
return new HttpNotFoundResult();
@ -118,7 +118,7 @@ namespace BuildFeed.Controllers
#endif
public async Task<ActionResult> TwitterCard(Guid id)
{
BuildModel b = await _bModel.SelectById(id);
Build b = await _bModel.SelectById(id);
if (b == null)
{
return new HttpNotFoundResult();
@ -170,7 +170,7 @@ namespace BuildFeed.Controllers
[Route("twitter/{id:long}/", Name = "Twitter (Legacy)")]
public async Task<ActionResult> TwitterCard(long id)
{
BuildModel b = await _bModel.SelectByLegacyId(id);
Build b = await _bModel.SelectByLegacyId(id);
if (b == null)
{
return new HttpNotFoundResult();
@ -203,7 +203,7 @@ namespace BuildFeed.Controllers
Value = lab
});
List<BuildModel> builds = await _bModel.SelectLab(lab, PAGE_SIZE, (page - 1) * PAGE_SIZE);
List<Build> builds = await _bModel.SelectLab(lab, PAGE_SIZE, (page - 1) * PAGE_SIZE);
ViewBag.ItemId = builds.FirstOrDefault()?.Lab;
ViewBag.PageNumber = page;
@ -239,7 +239,7 @@ namespace BuildFeed.Controllers
});
ViewBag.ItemId = MvcExtensions.GetDisplayTextForEnum(source);
List<BuildModel> builds = await _bModel.SelectSource(source, PAGE_SIZE, (page - 1) * PAGE_SIZE);
List<Build> builds = await _bModel.SelectSource(source, PAGE_SIZE, (page - 1) * PAGE_SIZE);
ViewBag.PageNumber = page;
ViewBag.PageCount = Math.Ceiling(Convert.ToDouble(await _bModel.SelectSourceCount(source)) / Convert.ToDouble(PAGE_SIZE));
@ -274,7 +274,7 @@ namespace BuildFeed.Controllers
});
ViewBag.ItemId = year.ToString();
List<BuildModel> builds = await _bModel.SelectYear(year, PAGE_SIZE, (page - 1) * PAGE_SIZE);
List<Build> builds = await _bModel.SelectYear(year, PAGE_SIZE, (page - 1) * PAGE_SIZE);
ViewBag.PageNumber = page;
ViewBag.PageCount = Math.Ceiling(await _bModel.SelectYearCount(year) / Convert.ToDouble(PAGE_SIZE));
@ -310,7 +310,7 @@ namespace BuildFeed.Controllers
});
ViewBag.ItemId = valueString;
List<BuildModel> builds = await _bModel.SelectVersion(major, minor, PAGE_SIZE, (page - 1) * PAGE_SIZE);
List<Build> builds = await _bModel.SelectVersion(major, minor, PAGE_SIZE, (page - 1) * PAGE_SIZE);
ViewBag.PageNumber = page;
ViewBag.PageCount = Math.Ceiling(Convert.ToDouble(await _bModel.SelectVersionCount(major, minor)) / Convert.ToDouble(PAGE_SIZE));
@ -326,7 +326,7 @@ namespace BuildFeed.Controllers
[Route("add/"), Authorize]
public ActionResult AddBuild()
{
BuildModel b = new BuildModel
Build b = new Build
{
SourceType = TypeOfSource.PrivateLeak
};
@ -334,7 +334,7 @@ namespace BuildFeed.Controllers
}
[Route("add/"), Authorize, HttpPost]
public async Task<ActionResult> AddBuild(BuildModel build)
public async Task<ActionResult> AddBuild(Build build)
{
if (ModelState.IsValid)
{
@ -368,12 +368,12 @@ namespace BuildFeed.Controllers
[Route("edit/{id}/"), Authorize]
public async Task<ActionResult> EditBuild(Guid id)
{
BuildModel b = await _bModel.SelectById(id);
Build b = await _bModel.SelectById(id);
return View(b);
}
[Route("edit/{id}/"), Authorize, HttpPost]
public async Task<ActionResult> EditBuild(Guid id, BuildModel build)
public async Task<ActionResult> EditBuild(Guid id, Build build)
{
if (ModelState.IsValid)
{

View File

@ -12,14 +12,14 @@ namespace BuildFeed.Controllers
public class RssController : BaseController
{
private const int RSS_SIZE = 25;
private readonly Build _bModel;
private readonly BuildRepository _bModel;
public RssController() { _bModel = new Build(); }
public RssController() { _bModel = new BuildRepository(); }
[Route("rss/compiled")]
public async Task<ActionResult> Index()
{
List<BuildModel> builds = await _bModel.SelectBuildsByCompileDate(RSS_SIZE);
List<Build> builds = await _bModel.SelectBuildsByCompileDate(RSS_SIZE);
Feed feed = new Feed
{
@ -49,7 +49,7 @@ namespace BuildFeed.Controllers
[Route("rss/added")]
public async Task<ActionResult> Added()
{
List<BuildModel> builds = await _bModel.SelectBuildsByAddedDate(RSS_SIZE);
List<Build> builds = await _bModel.SelectBuildsByAddedDate(RSS_SIZE);
Feed feed = new Feed
{
@ -79,7 +79,7 @@ namespace BuildFeed.Controllers
[Route("rss/leaked")]
public async Task<ActionResult> Leaked()
{
List<BuildModel> builds = await _bModel.SelectBuildsByLeakedDate(RSS_SIZE);
List<Build> builds = await _bModel.SelectBuildsByLeakedDate(RSS_SIZE);
Feed feed = new Feed
{
@ -109,7 +109,7 @@ namespace BuildFeed.Controllers
[Route("rss/version")]
public async Task<ActionResult> Version()
{
List<BuildModel> builds = await _bModel.SelectBuildsByOrder(RSS_SIZE);
List<Build> builds = await _bModel.SelectBuildsByOrder(RSS_SIZE);
Feed feed = new Feed
{
@ -138,7 +138,7 @@ namespace BuildFeed.Controllers
[Route("rss/lab/{lab}")]
public async Task<ActionResult> Lab(string lab)
{
List<BuildModel> builds = await _bModel.SelectLab(lab, RSS_SIZE);
List<Build> builds = await _bModel.SelectLab(lab, RSS_SIZE);
Feed feed = new Feed
{

View File

@ -16,9 +16,9 @@ namespace BuildFeed.Controllers
{
public class SupportController : BaseController
{
private readonly Build _bModel;
private readonly BuildRepository _bModel;
public SupportController() { _bModel = new Build(); }
public SupportController() { _bModel = new BuildRepository(); }
[Route("login/")]
public ActionResult Login() => View();
@ -138,7 +138,7 @@ namespace BuildFeed.Controllers
#endif
public async Task<ActionResult> Sitemap()
{
List<BuildModel> builds = await _bModel.SelectBuildsByOrder();
List<Build> builds = await _bModel.SelectBuildsByOrder();
Dictionary<string, SitemapPagedAction[]> actions = new Dictionary<string, SitemapPagedAction[]>
{
{
@ -291,7 +291,7 @@ namespace BuildFeed.Controllers
home.Add(new XElement(xn + "changefreq", "daily"));
xlist.Add(home);
foreach (BuildModel b in await _bModel.Select())
foreach (Build b in await _bModel.Select())
{
XElement url = new XElement(xn + "url");
url.Add(new XElement(xn + "loc",

View File

@ -1,5 +1,5 @@
@using BuildFeed.Model
@model BuildModel
@model Build
@{
ViewBag.Title = (string)ViewContext.RouteData.Values["action"] == "addBuild"
? $"{VariantTerms.Common_AddBuild} | {InvariantTerms.SiteName}"

View File

@ -1,7 +1,7 @@
@using System.Globalization
@using BuildFeed.Code
@using BuildFeed.Controllers
@model BuildFeed.Model.BuildModel
@model BuildFeed.Model.Build
@{
ViewBag.Title = $"{Model.FullBuildString} | {InvariantTerms.SiteName}";

View File

@ -1,7 +1,7 @@
@using BuildFeed.Code
@using BuildFeed.Model
@using Humanizer
@model Tuple<BuildGroup, List<BuildModel>>
@model Tuple<BuildGroup, List<Build>>
@{
ViewBag.Title = $"{Model.Item1} | {InvariantTerms.SiteName}";
}
@ -10,7 +10,7 @@
<h3>@VariantTerms.Front_Listing</h3>
<div class="build-group-listing">
@foreach (BuildModel build in Model.Item2)
@foreach (Build build in Model.Item2)
{
<div class="build-group">
<h3 class="build-group-title no-wrapping" title="@build.Lab">

View File

@ -1,7 +1,7 @@
@using BuildFeed.Code
@using BuildFeed.Model
@using Humanizer
@model IEnumerable<BuildModel>
@model IEnumerable<Build>
@{
ViewBag.Title = string.Format("{0}{1} | {2}", string.Format(VariantTerms.Front_BuildsFrom, ViewBag.ItemId), ViewBag.PageNumber == 1
? ""
@ -39,7 +39,7 @@
<br />
<h3>@VariantTerms.Front_Listing</h3>
<div class="build-group-listing">
@foreach (BuildModel build in Model)
@foreach (Build build in Model)
{
<div class="build-group">
<h3 class="build-group-title" title="@build.Lab">

View File

@ -1,7 +1,7 @@
@using BuildFeed.Code
@using BuildFeed.Model
@using Humanizer
@model IEnumerable<BuildModel>
@model IEnumerable<Build>
@{
ViewBag.Title = string.Format("{0}{1} | {2}", ViewBag.ItemId, ViewBag.PageNumber == 1
? ""
@ -33,7 +33,7 @@
<br />
<h3>@VariantTerms.Front_Listing</h3>
<div class="build-group-listing">
@foreach (BuildModel build in Model)
@foreach (Build build in Model)
{
<div class="build-group">
<h3 class="build-group-title" title="@build.Lab">

View File

@ -1,7 +1,7 @@
@using BuildFeed.Code
@using BuildFeed.Model
@using Humanizer
@model IEnumerable<BuildModel>
@model IEnumerable<Build>
@{
ViewBag.Title = $"{InvariantTerms.ProductName} {ViewBag.ItemId}{(ViewBag.PageNumber == 1 ? "" : string.Format(VariantTerms.Common_TitlePage, ViewBag.PageNumber))} | {InvariantTerms.SiteName}";
}
@ -31,7 +31,7 @@
<div class="addthis_sharing_toolbox"></div>
<h3>@VariantTerms.Front_Listing</h3>
<div class="build-group-listing">
@foreach (BuildModel build in Model)
@foreach (Build build in Model)
{
<div class="build-group">
<h3 class="build-group-title no-wrapping" title="@build.Lab">

View File

@ -1,7 +1,7 @@
@using BuildFeed.Code
@using BuildFeed.Model
@using Humanizer
@model IEnumerable<BuildModel>
@model IEnumerable<Build>
@{
ViewBag.Title = string.Format("{0}{1} | {2}", string.Format(VariantTerms.Front_BuildsFrom, ViewBag.ItemId), ViewBag.PageNumber == 1
? ""
@ -39,7 +39,7 @@
<br />
<h3>@VariantTerms.Front_Listing</h3>
<div class="build-group-listing">
@foreach (BuildModel build in Model)
@foreach (Build build in Model)
{
<div class="build-group">
<h3 class="build-group-title" title="@($"{build.MajorVersion}.{build.MinorVersion}.{build.Number}.{build.Revision}")">

View File

@ -3,6 +3,15 @@
@using BuildFeed.Controllers
@{
bool isRtl = CultureInfo.CurrentUICulture.TextInfo.IsRightToLeft;
Response.PushPromise("/res/css/default.min.css");
Response.PushPromise(VirtualPathUtility.ToAbsolute(((Theme)ViewBag.Theme).CssPath));
if (isRtl)
{
Response.PushPromise("/res/css/rtl.min.css");
}
Response.PushPromise("/res/ts/bfs.min.js");
}
<!DOCTYPE html>
<html dir="@(isRtl
@ -219,7 +228,7 @@
</div>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jsrender/1.0.0-rc.70/jsrender.min.js"></script>
<script type="text/javascript" src="~/res/ts/bfs.min.js"></script>
<script type="text/javascript" src="/res/ts/bfs.min.js"></script>
@RenderSection("scripts", false)
<script id="result-template" type="text/x-jsrender">
<a href="{{:Url}}" class="search-result-item" title="{{:Title}}">