diff --git a/.idea/.idea.c3stream/.idea/contentModel.xml b/.idea/.idea.c3stream/.idea/contentModel.xml index 0035be1..47136ac 100644 --- a/.idea/.idea.c3stream/.idea/contentModel.xml +++ b/.idea/.idea.c3stream/.idea/contentModel.xml @@ -5,6 +5,12 @@ + + + + + + @@ -37,10 +43,12 @@ - - - - + + + + + + @@ -108,31 +116,86 @@ - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DataModels/Database.cs b/DataModels/Database.cs new file mode 100644 index 0000000..5c17a7c --- /dev/null +++ b/DataModels/Database.cs @@ -0,0 +1,34 @@ +using System.Collections.Generic; +using System.Linq; +using c3stream.DataModels.Tables; +using LinqToDB; +using LinqToDB.Configuration; +using LinqToDB.Data; + +namespace c3stream.DataModels { + public class Database { + public class ConnectionStringSettings : IConnectionStringSettings { + public string ConnectionString { get; set; } + public string Name { get; set; } + public string ProviderName { get; set; } + public bool IsGlobal => false; + } + + public class Settings : ILinqToDBSettings { + public IEnumerable DataProviders => Enumerable.Empty(); + + public string DefaultConfiguration => "SQLite"; + public string DefaultDataProvider => "SQLite"; + + public IEnumerable ConnectionStrings { + get { yield return new ConnectionStringSettings {Name = "db", ProviderName = "SQLite", ConnectionString = @"Data Source=data/c3stream.sqlite;"}; } + } + } + + public class DbConn : DataConnection { + public DbConn() : base("db") { } + + public ITable States => GetTable(); + } + } +} \ No newline at end of file diff --git a/DataModels/Tables/States.cs b/DataModels/Tables/States.cs new file mode 100644 index 0000000..048b41a --- /dev/null +++ b/DataModels/Tables/States.cs @@ -0,0 +1,10 @@ +using LinqToDB.Mapping; + +namespace c3stream.DataModels.Tables { + [Table(Name = "States")] + public class States { + [Column(Name = "TalkId"), PrimaryKey, NotNull] public string TalkId { get; set; } + [Column(Name = "UserId"), PrimaryKey, NotNull] public string UserId { get; set; } + [Column(Name = "State"), NotNull] public string State { get; set; } + } +} \ No newline at end of file diff --git a/Pages/Conference.cshtml b/Pages/Conference.cshtml index cb82b0a..fcddad7 100644 --- a/Pages/Conference.cshtml +++ b/Pages/Conference.cshtml @@ -1,6 +1,7 @@ @page @model ConferenceModel @using System.Net +@using global::c3stream.DataModels @using static ConferenceModel @{ if (c3stream.Conferences.All(c => c.Acronym != Request.Query["c"])) { @@ -9,7 +10,6 @@ } c3stream.UpdateCookie(Request, Response, $"/Conference?c={Request.Query["c"]}"); - ReadUserData(); ViewData["Title"] = Request.Query["c"]; var wc = new WebClient(); var conference = c3stream.Conferences.First(c => c.Acronym == Request.Query["c"]); @@ -17,6 +17,8 @@ c3stream.UpdateConference(conference); } wc.Dispose(); + await using var db = new Database.DbConn(); + var states = db.States.ToList(); } @@ -34,7 +36,7 @@ @foreach (var talk in Request.Query["orderby"] == "published" ? conference.Talks.OrderByDescending(p => p.ReleaseDate) : conference.Talks.OrderBy(p => p.Date)) { - var state = UserData.FirstOrDefault(p => p.TalkId == talk.Guid && p.UserId == Request.Cookies["bookmark"])?.State; + var state = states.FirstOrDefault(p => p.TalkId == talk.Guid && p.UserId == Request.Cookies["bookmark"])?.State; var isWatched = state == "watched"; var isMarked = state == "marked"; var file = $"{talk.Slug}.mp4"; @@ -66,43 +68,43 @@
@talk.OriginalLanguage
- + @if (System.IO.File.Exists(System.IO.Path.Combine(c3stream.CachePath, conference.Acronym, file))) { - + } else { - + } - + @if (isWatched) { - - } else if (isMarked) { - - } else { - - } diff --git a/Pages/Conference.cshtml.cs b/Pages/Conference.cshtml.cs index a757866..7cb7be7 100644 --- a/Pages/Conference.cshtml.cs +++ b/Pages/Conference.cshtml.cs @@ -1,58 +1,39 @@ using System.Collections.Generic; using System.Linq; +using c3stream.DataModels; +using c3stream.DataModels.Tables; +using LinqToDB; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.Extensions.Logging; using Newtonsoft.Json; namespace c3stream.Pages { public class ConferenceModel : PageModel { - public static List UserData = new List(); private readonly ILogger _logger; public ConferenceModel(ILogger logger) => _logger = logger; public void OnGet() { - var guid = Request.Query["guid"]; - var state = Request.Query["state"]; + var guid = Request.Query["guid"].ToString(); + var state = Request.Query["state"].ToString(); var userid = Request.Cookies["bookmark"]; if (string.IsNullOrWhiteSpace(guid) || string.IsNullOrWhiteSpace(state) || !Request.Cookies.ContainsKey("bookmark")) return; - lock (c3stream.Lock) { - ReadUserData(); - var existing = UserData.FirstOrDefault(p => p.TalkId == guid && p.UserId == userid); - if (existing != null) - if (state == "unwatched") - UserData.Remove(existing); - else - existing.State = state; - else - UserData.Add(new UserStatus(userid, guid, state)); - WriteUserData(); - Response.Redirect("/"); - } - } - - public static void ReadUserData() { - lock (c3stream.Lock) - UserData = JsonConvert.DeserializeObject>(System.IO.File.ReadAllText(c3stream.DbPath)); - } - - public static void WriteUserData() { - lock (c3stream.Lock) - System.IO.File.WriteAllText(c3stream.DbPath, JsonConvert.SerializeObject(UserData)); - } - - public class UserStatus { - public readonly string TalkId; - public readonly string UserId; - public string State; - - public UserStatus(string userId, string talkId, string state = "unwatched") { - UserId = userId; - State = state; - TalkId = talkId; - } + using var db = new Database.DbConn(); + var existing = db.States.FirstOrDefault(p => p.TalkId == guid && p.UserId == userid); + if (existing != null) + if (state == "unwatched") + db.States.Delete(p => p == existing); + else { + existing.State = state; + db.Update(existing); + } + else + db.Insert(new States { + State = state, TalkId = guid, UserId = userid + }); + Response.Redirect("/"); } } } \ No newline at end of file diff --git a/Pages/Info.cshtml b/Pages/Info.cshtml index 234321c..171cc9a 100644 --- a/Pages/Info.cshtml +++ b/Pages/Info.cshtml @@ -1,4 +1,5 @@ @page +@using global::c3stream.DataModels @model InfoModel @{ ViewData["Title"] = "Info"; @@ -10,10 +11,11 @@ } c3stream.UpdateCookie(Request, Response, $"/Info?guid={Request.Query["guid"]}"); + + await using var db = new Database.DbConn(); - ConferenceModel.ReadUserData(); var talk = c3stream.GetEventByGuid(Request.Query["guid"]); - var state = ConferenceModel.UserData.FirstOrDefault(p => p.TalkId == Request.Query["guid"] && p.UserId == Request.Cookies["bookmark"])?.State; + var state = db.States.FirstOrDefault(p => p.TalkId == Request.Query["guid"].ToString() && p.UserId == Request.Cookies["bookmark"])?.State; if (talk == null) { Response.Redirect("/"); return; @@ -44,6 +46,7 @@ 3 => talk.Tags[2], 4 => talk.Tags[3], 5 => talk.Tags[3], + 6 => talk.Tags[3], // rc3: is this correct? _ => "" }; } @@ -67,40 +70,40 @@ else {
@eventName - @category - @talk.Date?.Date.ToShortDateString()
- + @if (System.IO.File.Exists(System.IO.Path.Combine(c3stream.CachePath, conference.Acronym, file))) { - + } else { - + } @if (isWatched) { - - } else if (isMarked) { - - } else { - - } diff --git a/c3stream.cs b/c3stream.cs index 51e8dc6..82706a4 100644 --- a/c3stream.cs +++ b/c3stream.cs @@ -3,7 +3,10 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; +using c3stream.DataModels; using c3stream.Pages; +using LinqToDB.Common; +using LinqToDB.Data; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Hosting; @@ -11,13 +14,13 @@ using Microsoft.Extensions.Hosting; namespace c3stream { public static class c3stream { public const string DataPath = "data"; - public const string DbFile = "c3stream.user.json"; + public const string DbFile = "c3stream.sqlite"; public const string CachePath = "/mnt/storage/archive/Video/congress/"; public const string CacheUrl = "https://c3stream-mirror.zotan.services/"; - public static object Lock = new object(); + public static object Lock = new(); public static string DbPath = Path.Combine(DataPath, DbFile); - public static List Conferences = new List { + public static readonly List Conferences = new() { new ConferenceObject("rc3", true), new ConferenceObject("36c3"), new ConferenceObject("camp2019"), @@ -34,7 +37,9 @@ namespace c3stream { if (!Directory.Exists(DataPath)) Directory.CreateDirectory(DataPath); if (!File.Exists(DbPath)) - ConferenceModel.WriteUserData(); + File.Copy(Path.Combine(DataPath, "database.init.sqlite"), DbPath); + + DataConnection.DefaultSettings = new Database.Settings(); foreach (var conference in Conferences) UpdateConference(conference); @@ -55,6 +60,7 @@ namespace c3stream { } } + //TODO: move this to the database as well public static void UpdateConference(ConferenceObject conference) { using var wc = new WebClient(); @@ -111,7 +117,7 @@ namespace c3stream { public string Acronym; public bool Ongoing; public string LogoUri; - public List Talks = new List(); + public List Talks = new(); public ConferenceObject(string acronym, bool ongoing = false) { Acronym = acronym; diff --git a/c3stream.csproj b/c3stream.csproj index 29d31c4..2dc0349 100644 --- a/c3stream.csproj +++ b/c3stream.csproj @@ -1,10 +1,14 @@ - netcoreapp3.1 + net50 + Release;Debug + x64 + + @@ -32,5 +36,7 @@ - + + + diff --git a/c3stream.sln b/c3stream.sln index cb5804c..11f7453 100644 --- a/c3stream.sln +++ b/c3stream.sln @@ -4,13 +4,13 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "c3stream", "c3stream.csproj EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU + Debug|x64 = Debug|x64 + Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {BC6A24FE-B35F-4F0A-8E8E-221E61E41EEF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BC6A24FE-B35F-4F0A-8E8E-221E61E41EEF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BC6A24FE-B35F-4F0A-8E8E-221E61E41EEF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BC6A24FE-B35F-4F0A-8E8E-221E61E41EEF}.Release|Any CPU.Build.0 = Release|Any CPU + {BC6A24FE-B35F-4F0A-8E8E-221E61E41EEF}.Debug|x64.ActiveCfg = Debug|x64 + {BC6A24FE-B35F-4F0A-8E8E-221E61E41EEF}.Debug|x64.Build.0 = Debug|x64 + {BC6A24FE-B35F-4F0A-8E8E-221E61E41EEF}.Release|x64.ActiveCfg = Release|x64 + {BC6A24FE-B35F-4F0A-8E8E-221E61E41EEF}.Release|x64.Build.0 = Release|x64 EndGlobalSection EndGlobal diff --git a/wwwroot/css/site.css b/wwwroot/css/site.css index 5062340..72a1705 100644 --- a/wwwroot/css/site.css +++ b/wwwroot/css/site.css @@ -88,6 +88,9 @@ body { color: #ffffff; border-color: #3c6385; background-color: #375a7a; +} + +.btn-c3saction { width: 42px !important; }