migrate to database storage, fix css goofs
This commit is contained in:
parent
c90ebab27c
commit
5971c8ff5d
|
@ -5,6 +5,12 @@
|
||||||
<e p="$USER_HOME$/.cache/JetBrains/Rider2020.3/resharper-host/local/Transient/Rider/v203/SolutionCaches/_c3stream.-187536235.00" t="ExcludeRecursive" />
|
<e p="$USER_HOME$/.cache/JetBrains/Rider2020.3/resharper-host/local/Transient/Rider/v203/SolutionCaches/_c3stream.-187536235.00" t="ExcludeRecursive" />
|
||||||
<e p="$PROJECT_DIR$" t="IncludeRecursive">
|
<e p="$PROJECT_DIR$" t="IncludeRecursive">
|
||||||
<e p=".gitignore" t="Include" />
|
<e p=".gitignore" t="Include" />
|
||||||
|
<e p="DataModels" t="Include">
|
||||||
|
<e p="Database.cs" t="Include" />
|
||||||
|
<e p="Tables" t="Include">
|
||||||
|
<e p="States.cs" t="Include" />
|
||||||
|
</e>
|
||||||
|
</e>
|
||||||
<e p="LICENSE" t="Include" />
|
<e p="LICENSE" t="Include" />
|
||||||
<e p="Pages" t="Include">
|
<e p="Pages" t="Include">
|
||||||
<e p="Conference.cshtml" t="Include" />
|
<e p="Conference.cshtml" t="Include" />
|
||||||
|
@ -37,10 +43,12 @@
|
||||||
<e p="c3stream.csproj" t="IncludeRecursive" />
|
<e p="c3stream.csproj" t="IncludeRecursive" />
|
||||||
<e p="c3stream.sln" t="IncludeFlat" />
|
<e p="c3stream.sln" t="IncludeFlat" />
|
||||||
<e p="obj" t="ExcludeRecursive">
|
<e p="obj" t="ExcludeRecursive">
|
||||||
<e p="Debug" t="Include">
|
<e p="x64" t="Include">
|
||||||
<e p="netcoreapp3.1" t="Include">
|
<e p="Debug" t="Include">
|
||||||
<e p="c3stream.AssemblyInfo.cs" t="Include" />
|
<e p="net50" t="Include">
|
||||||
<e p="c3stream.RazorAssemblyInfo.cs" t="Include" />
|
<e p="c3stream.AssemblyInfo.cs" t="Include" />
|
||||||
|
<e p="c3stream.RazorAssemblyInfo.cs" t="Include" />
|
||||||
|
</e>
|
||||||
</e>
|
</e>
|
||||||
</e>
|
</e>
|
||||||
</e>
|
</e>
|
||||||
|
@ -108,31 +116,86 @@
|
||||||
</e>
|
</e>
|
||||||
</e>
|
</e>
|
||||||
<e p="webfonts" t="Include">
|
<e p="webfonts" t="Include">
|
||||||
<e p="fa-brands-400.eot" t="Include" />
|
<e p="pro-fa-brands-400-5.0.0.woff2" t="Include" />
|
||||||
<e p="fa-brands-400.svg" t="Include" />
|
<e p="pro-fa-brands-400-5.12.0.woff2" t="Include" />
|
||||||
<e p="fa-brands-400.ttf" t="Include" />
|
<e p="pro-fa-brands-400-5.3.0.woff2" t="Include" />
|
||||||
<e p="fa-brands-400.woff" t="Include" />
|
<e p="pro-fa-brands-400-5.8.0.woff2" t="Include" />
|
||||||
<e p="fa-brands-400.woff2" t="Include" />
|
<e p="pro-fa-duotone-900-5.0.0.woff2" t="Include" />
|
||||||
<e p="fa-duotone-900.eot" t="Include" />
|
<e p="pro-fa-duotone-900-5.0.10.woff2" t="Include" />
|
||||||
<e p="fa-duotone-900.svg" t="Include" />
|
<e p="pro-fa-duotone-900-5.0.11.woff2" t="Include" />
|
||||||
<e p="fa-duotone-900.ttf" t="Include" />
|
<e p="pro-fa-duotone-900-5.0.13.woff2" t="Include" />
|
||||||
<e p="fa-duotone-900.woff" t="Include" />
|
<e p="pro-fa-duotone-900-5.0.3.woff2" t="Include" />
|
||||||
<e p="fa-duotone-900.woff2" t="Include" />
|
<e p="pro-fa-duotone-900-5.0.5.woff2" t="Include" />
|
||||||
<e p="fa-light-300.eot" t="Include" />
|
<e p="pro-fa-duotone-900-5.0.7.woff2" t="Include" />
|
||||||
<e p="fa-light-300.svg" t="Include" />
|
<e p="pro-fa-duotone-900-5.0.9.woff2" t="Include" />
|
||||||
<e p="fa-light-300.ttf" t="Include" />
|
<e p="pro-fa-duotone-900-5.1.0.woff2" t="Include" />
|
||||||
<e p="fa-light-300.woff" t="Include" />
|
<e p="pro-fa-duotone-900-5.10.1.woff2" t="Include" />
|
||||||
<e p="fa-light-300.woff2" t="Include" />
|
<e p="pro-fa-duotone-900-5.10.2.woff2" t="Include" />
|
||||||
<e p="fa-regular-400.eot" t="Include" />
|
<e p="pro-fa-duotone-900-5.11.0.woff2" t="Include" />
|
||||||
<e p="fa-regular-400.svg" t="Include" />
|
<e p="pro-fa-duotone-900-5.11.1.woff2" t="Include" />
|
||||||
<e p="fa-regular-400.ttf" t="Include" />
|
<e p="pro-fa-duotone-900-5.12.0.woff2" t="Include" />
|
||||||
<e p="fa-regular-400.woff" t="Include" />
|
<e p="pro-fa-duotone-900-5.2.0.woff2" t="Include" />
|
||||||
<e p="fa-regular-400.woff2" t="Include" />
|
<e p="pro-fa-duotone-900-5.3.0.woff2" t="Include" />
|
||||||
<e p="fa-solid-900.eot" t="Include" />
|
<e p="pro-fa-duotone-900-5.4.0.woff2" t="Include" />
|
||||||
<e p="fa-solid-900.svg" t="Include" />
|
<e p="pro-fa-duotone-900-5.8.0.woff2" t="Include" />
|
||||||
<e p="fa-solid-900.ttf" t="Include" />
|
<e p="pro-fa-duotone-900-5.9.0.woff2" t="Include" />
|
||||||
<e p="fa-solid-900.woff" t="Include" />
|
<e p="pro-fa-light-300-5.0.0.woff2" t="Include" />
|
||||||
<e p="fa-solid-900.woff2" t="Include" />
|
<e p="pro-fa-light-300-5.0.10.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-light-300-5.0.11.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-light-300-5.0.13.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-light-300-5.0.3.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-light-300-5.0.5.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-light-300-5.0.7.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-light-300-5.0.9.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-light-300-5.1.0.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-light-300-5.10.1.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-light-300-5.10.2.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-light-300-5.11.0.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-light-300-5.11.1.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-light-300-5.12.0.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-light-300-5.2.0.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-light-300-5.3.0.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-light-300-5.4.0.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-light-300-5.8.0.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-light-300-5.9.0.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-regular-400-5.0.0.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-regular-400-5.0.10.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-regular-400-5.0.11.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-regular-400-5.0.13.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-regular-400-5.0.3.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-regular-400-5.0.5.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-regular-400-5.0.7.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-regular-400-5.0.9.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-regular-400-5.1.0.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-regular-400-5.10.1.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-regular-400-5.10.2.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-regular-400-5.11.0.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-regular-400-5.11.1.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-regular-400-5.12.0.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-regular-400-5.2.0.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-regular-400-5.3.0.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-regular-400-5.4.0.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-regular-400-5.8.0.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-regular-400-5.9.0.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-solid-900-5.0.0.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-solid-900-5.0.11.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-solid-900-5.0.13.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-solid-900-5.0.3.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-solid-900-5.0.5.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-solid-900-5.0.7.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-solid-900-5.0.9.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-solid-900-5.1.0.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-solid-900-5.10.1.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-solid-900-5.10.2.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-solid-900-5.11.0.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-solid-900-5.11.1.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-solid-900-5.12.0.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-solid-900-5.12.1.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-solid-900-5.2.0.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-solid-900-5.3.0.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-solid-900-5.4.0.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-solid-900-5.8.0.woff2" t="Include" />
|
||||||
|
<e p="pro-fa-solid-900-5.9.0.woff2" t="Include" />
|
||||||
</e>
|
</e>
|
||||||
</e>
|
</e>
|
||||||
</e>
|
</e>
|
||||||
|
|
34
DataModels/Database.cs
Normal file
34
DataModels/Database.cs
Normal file
|
@ -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<IDataProviderSettings> DataProviders => Enumerable.Empty<IDataProviderSettings>();
|
||||||
|
|
||||||
|
public string DefaultConfiguration => "SQLite";
|
||||||
|
public string DefaultDataProvider => "SQLite";
|
||||||
|
|
||||||
|
public IEnumerable<IConnectionStringSettings> 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> States => GetTable<States>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
10
DataModels/Tables/States.cs
Normal file
10
DataModels/Tables/States.cs
Normal file
|
@ -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; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
@page
|
@page
|
||||||
@model ConferenceModel
|
@model ConferenceModel
|
||||||
@using System.Net
|
@using System.Net
|
||||||
|
@using global::c3stream.DataModels
|
||||||
@using static ConferenceModel
|
@using static ConferenceModel
|
||||||
@{
|
@{
|
||||||
if (c3stream.Conferences.All(c => c.Acronym != Request.Query["c"])) {
|
if (c3stream.Conferences.All(c => c.Acronym != Request.Query["c"])) {
|
||||||
|
@ -9,7 +10,6 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
c3stream.UpdateCookie(Request, Response, $"/Conference?c={Request.Query["c"]}");
|
c3stream.UpdateCookie(Request, Response, $"/Conference?c={Request.Query["c"]}");
|
||||||
ReadUserData();
|
|
||||||
ViewData["Title"] = Request.Query["c"];
|
ViewData["Title"] = Request.Query["c"];
|
||||||
var wc = new WebClient();
|
var wc = new WebClient();
|
||||||
var conference = c3stream.Conferences.First(c => c.Acronym == Request.Query["c"]);
|
var conference = c3stream.Conferences.First(c => c.Acronym == Request.Query["c"]);
|
||||||
|
@ -17,6 +17,8 @@
|
||||||
c3stream.UpdateConference(conference);
|
c3stream.UpdateConference(conference);
|
||||||
}
|
}
|
||||||
wc.Dispose();
|
wc.Dispose();
|
||||||
|
await using var db = new Database.DbConn();
|
||||||
|
var states = db.States.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
<table class="table">
|
<table class="table">
|
||||||
|
@ -34,7 +36,7 @@
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@foreach (var talk in Request.Query["orderby"] == "published" ? conference.Talks.OrderByDescending(p => p.ReleaseDate) : conference.Talks.OrderBy(p => p.Date)) {
|
@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 isWatched = state == "watched";
|
||||||
var isMarked = state == "marked";
|
var isMarked = state == "marked";
|
||||||
var file = $"{talk.Slug}.mp4";
|
var file = $"{talk.Slug}.mp4";
|
||||||
|
@ -66,43 +68,43 @@
|
||||||
<td>@talk.OriginalLanguage</td>
|
<td>@talk.OriginalLanguage</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="btn-group" role="group">
|
<div class="btn-group" role="group">
|
||||||
<a href="@talk.FrontendLink.AbsoluteUri" role="button" class="btn btn-primary w-100" data-toggle="tooltip" data-placement="top" title="Play">
|
<a href="@talk.FrontendLink.AbsoluteUri" role="button" class="btn btn-primary btn-c3saction w-100" data-toggle="tooltip" data-placement="top" title="Play">
|
||||||
<i class="fas fa-play-circle"></i>
|
<i class="fas fa-play-circle"></i>
|
||||||
</a>
|
</a>
|
||||||
@if (System.IO.File.Exists(System.IO.Path.Combine(c3stream.CachePath, conference.Acronym, file))) {
|
@if (System.IO.File.Exists(System.IO.Path.Combine(c3stream.CachePath, conference.Acronym, file))) {
|
||||||
<a href="@(c3stream.CacheUrl + $"{conference.Acronym}/{file}")" role="button" class="btn btn-primary w-100" data-toggle="tooltip" data-placement="top" title="Mirror">
|
<a href="@(c3stream.CacheUrl + $"{conference.Acronym}/{file}")" role="button" class="btn btn-primary btn-c3saction w-100" data-toggle="tooltip" data-placement="top" title="Mirror">
|
||||||
<i class="fas fa-cloud-download"></i>
|
<i class="fas fa-cloud-download"></i>
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
<a href="/" role="button" class="btn btn-primary disabled">
|
<a href="/" role="button" class="btn btn-primary btn-c3saction disabled">
|
||||||
<i class="fas fa-cloud-download"></i>
|
<i class="fas fa-cloud-download"></i>
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
<a href="/Info?guid=@talk.Guid" role="button" class="btn btn-primary w-100" data-toggle="tooltip" data-placement="top" title="Info">
|
<a href="/Info?guid=@talk.Guid" role="button" class="btn btn-primary btn-c3saction w-100" data-toggle="tooltip" data-placement="top" title="Info">
|
||||||
<i class="fas fa-info-circle"></i>
|
<i class="fas fa-info-circle"></i>
|
||||||
</a>
|
</a>
|
||||||
@if (isWatched) {
|
@if (isWatched) {
|
||||||
<button onclick="SetState('@talk.Guid', 'unwatched')" class="btn btn-primary w-100" data-toggle="tooltip" data-placement="top" title="Mark unwatched">
|
<button onclick="SetState('@talk.Guid', 'unwatched')" class="btn btn-primary btn-c3saction w-100" data-toggle="tooltip" data-placement="top" title="Mark unwatched">
|
||||||
<i class="fas fa-times"></i>
|
<i class="fas fa-times"></i>
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-primary disabled">
|
<button class="btn btn-primary btn-c3saction disabled">
|
||||||
<i class="fas fa-clock"></i>
|
<i class="fas fa-clock"></i>
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
else if (isMarked) {
|
else if (isMarked) {
|
||||||
<button onclick="SetState('@talk.Guid', 'watched')" class="btn btn-primary w-100" data-toggle="tooltip" data-placement="top" title="Mark watched">
|
<button onclick="SetState('@talk.Guid', 'watched')" class="btn btn-primary btn-c3saction w-100" data-toggle="tooltip" data-placement="top" title="Mark watched">
|
||||||
<i class="fas fa-check"></i>
|
<i class="fas fa-check"></i>
|
||||||
</button>
|
</button>
|
||||||
<button onclick="SetState('@talk.Guid', 'unwatched')" class="btn btn-primary w-100" data-toggle="tooltip" data-placement="top" title="Remove from watch later">
|
<button onclick="SetState('@talk.Guid', 'unwatched')" class="btn btn-primary btn-c3saction w-100" data-toggle="tooltip" data-placement="top" title="Remove from watch later">
|
||||||
<i class="fas fa-undo-alt"></i>
|
<i class="fas fa-undo-alt"></i>
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
<button onclick="SetState('@talk.Guid', 'watched')" class="btn btn-primary w-100" data-toggle="tooltip" data-placement="top" title="Mark watched">
|
<button onclick="SetState('@talk.Guid', 'watched')" class="btn btn-primary btn-c3saction w-100" data-toggle="tooltip" data-placement="top" title="Mark watched">
|
||||||
<i class="fas fa-check"></i>
|
<i class="fas fa-check"></i>
|
||||||
</button>
|
</button>
|
||||||
<button onclick="SetState('@talk.Guid', 'marked')" class="btn btn-primary w-100" data-toggle="tooltip" data-placement="top" title="Add to watch later">
|
<button onclick="SetState('@talk.Guid', 'marked')" class="btn btn-primary btn-c3saction w-100" data-toggle="tooltip" data-placement="top" title="Add to watch later">
|
||||||
<i class="fas fa-clock"></i>
|
<i class="fas fa-clock"></i>
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,58 +1,39 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using c3stream.DataModels;
|
||||||
|
using c3stream.DataModels.Tables;
|
||||||
|
using LinqToDB;
|
||||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace c3stream.Pages {
|
namespace c3stream.Pages {
|
||||||
public class ConferenceModel : PageModel {
|
public class ConferenceModel : PageModel {
|
||||||
public static List<UserStatus> UserData = new List<UserStatus>();
|
|
||||||
private readonly ILogger<ConferenceModel> _logger;
|
private readonly ILogger<ConferenceModel> _logger;
|
||||||
|
|
||||||
public ConferenceModel(ILogger<ConferenceModel> logger) => _logger = logger;
|
public ConferenceModel(ILogger<ConferenceModel> logger) => _logger = logger;
|
||||||
|
|
||||||
public void OnGet() {
|
public void OnGet() {
|
||||||
var guid = Request.Query["guid"];
|
var guid = Request.Query["guid"].ToString();
|
||||||
var state = Request.Query["state"];
|
var state = Request.Query["state"].ToString();
|
||||||
var userid = Request.Cookies["bookmark"];
|
var userid = Request.Cookies["bookmark"];
|
||||||
if (string.IsNullOrWhiteSpace(guid) || string.IsNullOrWhiteSpace(state) || !Request.Cookies.ContainsKey("bookmark"))
|
if (string.IsNullOrWhiteSpace(guid) || string.IsNullOrWhiteSpace(state) || !Request.Cookies.ContainsKey("bookmark"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
lock (c3stream.Lock) {
|
using var db = new Database.DbConn();
|
||||||
ReadUserData();
|
var existing = db.States.FirstOrDefault(p => p.TalkId == guid && p.UserId == userid);
|
||||||
var existing = UserData.FirstOrDefault(p => p.TalkId == guid && p.UserId == userid);
|
if (existing != null)
|
||||||
if (existing != null)
|
if (state == "unwatched")
|
||||||
if (state == "unwatched")
|
db.States.Delete(p => p == existing);
|
||||||
UserData.Remove(existing);
|
else {
|
||||||
else
|
existing.State = state;
|
||||||
existing.State = state;
|
db.Update(existing);
|
||||||
else
|
}
|
||||||
UserData.Add(new UserStatus(userid, guid, state));
|
else
|
||||||
WriteUserData();
|
db.Insert(new States {
|
||||||
Response.Redirect("/");
|
State = state, TalkId = guid, UserId = userid
|
||||||
}
|
});
|
||||||
}
|
Response.Redirect("/");
|
||||||
|
|
||||||
public static void ReadUserData() {
|
|
||||||
lock (c3stream.Lock)
|
|
||||||
UserData = JsonConvert.DeserializeObject<List<UserStatus>>(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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
@page
|
@page
|
||||||
|
@using global::c3stream.DataModels
|
||||||
@model InfoModel
|
@model InfoModel
|
||||||
@{
|
@{
|
||||||
ViewData["Title"] = "Info";
|
ViewData["Title"] = "Info";
|
||||||
|
@ -10,10 +11,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
c3stream.UpdateCookie(Request, Response, $"/Info?guid={Request.Query["guid"]}");
|
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 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) {
|
if (talk == null) {
|
||||||
Response.Redirect("/");
|
Response.Redirect("/");
|
||||||
return;
|
return;
|
||||||
|
@ -44,6 +46,7 @@
|
||||||
3 => talk.Tags[2],
|
3 => talk.Tags[2],
|
||||||
4 => talk.Tags[3],
|
4 => talk.Tags[3],
|
||||||
5 => talk.Tags[3],
|
5 => talk.Tags[3],
|
||||||
|
6 => talk.Tags[3], // rc3: is this correct?
|
||||||
_ => "<unknown tag format>"
|
_ => "<unknown tag format>"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -67,40 +70,40 @@ else {
|
||||||
|
|
||||||
<h5>@eventName - @category - @talk.Date?.Date.ToShortDateString()</h5>
|
<h5>@eventName - @category - @talk.Date?.Date.ToShortDateString()</h5>
|
||||||
<div class="btn-group" role="group" style="margin-bottom: 10px">
|
<div class="btn-group" role="group" style="margin-bottom: 10px">
|
||||||
<a href="@talk.FrontendLink.AbsoluteUri" role="button" class="btn btn-primary w-100" data-toggle="tooltip" data-placement="right" title="Play">
|
<a href="@talk.FrontendLink.AbsoluteUri" role="button" class="btn btn-primary btn-c3saction w-100" data-toggle="tooltip" data-placement="right" title="Play">
|
||||||
<i class="fas fa-play-circle"></i>
|
<i class="fas fa-play-circle"></i>
|
||||||
</a>
|
</a>
|
||||||
@if (System.IO.File.Exists(System.IO.Path.Combine(c3stream.CachePath, conference.Acronym, file))) {
|
@if (System.IO.File.Exists(System.IO.Path.Combine(c3stream.CachePath, conference.Acronym, file))) {
|
||||||
<a href="@(c3stream.CacheUrl + $"{conference.Acronym}/{file}")" role="button" class="btn btn-primary w-100" data-toggle="tooltip" data-placement="right" title="Mirror">
|
<a href="@(c3stream.CacheUrl + $"{conference.Acronym}/{file}")" role="button" class="btn btn-primary btn-c3saction w-100" data-toggle="tooltip" data-placement="right" title="Mirror">
|
||||||
<i class="fas fa-cloud-download"></i>
|
<i class="fas fa-cloud-download"></i>
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
<a href="/" role="button" class="btn btn-primary disabled">
|
<a href="/" role="button" class="btn btn-primary btn-c3saction disabled">
|
||||||
<i class="fas fa-cloud-download"></i>
|
<i class="fas fa-cloud-download"></i>
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
@if (isWatched) {
|
@if (isWatched) {
|
||||||
<button onclick="SetState('@talk.Guid', 'unwatched')" class="btn btn-primary w-100" data-toggle="tooltip" data-placement="left" title="Mark unwatched">
|
<button onclick="SetState('@talk.Guid', 'unwatched')" class="btn btn-primary btn-c3saction w-100" data-toggle="tooltip" data-placement="left" title="Mark unwatched">
|
||||||
<i class="fas fa-times"></i>
|
<i class="fas fa-times"></i>
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-primary disabled">
|
<button class="btn btn-primary btn-c3saction disabled">
|
||||||
<i class="fas fa-clock"></i>
|
<i class="fas fa-clock"></i>
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
else if (isMarked) {
|
else if (isMarked) {
|
||||||
<button onclick="SetState('@talk.Guid', 'watched')" class="btn btn-primary w-100" data-toggle="tooltip" data-placement="left" title="Mark watched">
|
<button onclick="SetState('@talk.Guid', 'watched')" class="btn btn-primary btn-c3saction w-100" data-toggle="tooltip" data-placement="left" title="Mark watched">
|
||||||
<i class="fas fa-check"></i>
|
<i class="fas fa-check"></i>
|
||||||
</button>
|
</button>
|
||||||
<button onclick="SetState('@talk.Guid', 'unwatched')" class="btn btn-primary w-100" data-toggle="tooltip" data-placement="left" title="Remove from watch later">
|
<button onclick="SetState('@talk.Guid', 'unwatched')" class="btn btn-primary btn-c3saction w-100" data-toggle="tooltip" data-placement="left" title="Remove from watch later">
|
||||||
<i class="fas fa-undo-alt"></i>
|
<i class="fas fa-undo-alt"></i>
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
<button onclick="SetState('@talk.Guid', 'watched')" class="btn btn-primary w-100" data-toggle="tooltip" data-placement="left" title="Mark watched">
|
<button onclick="SetState('@talk.Guid', 'watched')" class="btn btn-primary btn-c3saction w-100" data-toggle="tooltip" data-placement="left" title="Mark watched">
|
||||||
<i class="fas fa-check"></i>
|
<i class="fas fa-check"></i>
|
||||||
</button>
|
</button>
|
||||||
<button onclick="SetState('@talk.Guid', 'marked')" class="btn btn-primary w-100" data-toggle="tooltip" data-placement="left" title="Add to watch later">
|
<button onclick="SetState('@talk.Guid', 'marked')" class="btn btn-primary btn-c3saction w-100" data-toggle="tooltip" data-placement="left" title="Add to watch later">
|
||||||
<i class="fas fa-clock"></i>
|
<i class="fas fa-clock"></i>
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
|
|
16
c3stream.cs
16
c3stream.cs
|
@ -3,7 +3,10 @@ using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using c3stream.DataModels;
|
||||||
using c3stream.Pages;
|
using c3stream.Pages;
|
||||||
|
using LinqToDB.Common;
|
||||||
|
using LinqToDB.Data;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
|
@ -11,13 +14,13 @@ using Microsoft.Extensions.Hosting;
|
||||||
namespace c3stream {
|
namespace c3stream {
|
||||||
public static class c3stream {
|
public static class c3stream {
|
||||||
public const string DataPath = "data";
|
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 CachePath = "/mnt/storage/archive/Video/congress/";
|
||||||
public const string CacheUrl = "https://c3stream-mirror.zotan.services/";
|
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 string DbPath = Path.Combine(DataPath, DbFile);
|
||||||
|
|
||||||
public static List<ConferenceObject> Conferences = new List<ConferenceObject> {
|
public static readonly List<ConferenceObject> Conferences = new() {
|
||||||
new ConferenceObject("rc3", true),
|
new ConferenceObject("rc3", true),
|
||||||
new ConferenceObject("36c3"),
|
new ConferenceObject("36c3"),
|
||||||
new ConferenceObject("camp2019"),
|
new ConferenceObject("camp2019"),
|
||||||
|
@ -34,7 +37,9 @@ namespace c3stream {
|
||||||
if (!Directory.Exists(DataPath))
|
if (!Directory.Exists(DataPath))
|
||||||
Directory.CreateDirectory(DataPath);
|
Directory.CreateDirectory(DataPath);
|
||||||
if (!File.Exists(DbPath))
|
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)
|
foreach (var conference in Conferences)
|
||||||
UpdateConference(conference);
|
UpdateConference(conference);
|
||||||
|
@ -55,6 +60,7 @@ namespace c3stream {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: move this to the database as well
|
||||||
public static void UpdateConference(ConferenceObject conference) {
|
public static void UpdateConference(ConferenceObject conference) {
|
||||||
using var wc = new WebClient();
|
using var wc = new WebClient();
|
||||||
|
|
||||||
|
@ -111,7 +117,7 @@ namespace c3stream {
|
||||||
public string Acronym;
|
public string Acronym;
|
||||||
public bool Ongoing;
|
public bool Ongoing;
|
||||||
public string LogoUri;
|
public string LogoUri;
|
||||||
public List<Event> Talks = new List<Event>();
|
public List<Event> Talks = new();
|
||||||
|
|
||||||
public ConferenceObject(string acronym, bool ongoing = false) {
|
public ConferenceObject(string acronym, bool ongoing = false) {
|
||||||
Acronym = acronym;
|
Acronym = acronym;
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
<TargetFramework>net50</TargetFramework>
|
||||||
|
<Configurations>Release;Debug</Configurations>
|
||||||
|
<Platforms>x64</Platforms>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="linq2db" Version="3.2.2" />
|
||||||
|
<PackageReference Include="Microsoft.Data.Sqlite" Version="5.0.1" PrivateAssets="none" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
@ -32,5 +36,7 @@
|
||||||
<Content Remove="data\**" />
|
<Content Remove="data\**" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="DataModels" />
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
12
c3stream.sln
12
c3stream.sln
|
@ -4,13 +4,13 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "c3stream", "c3stream.csproj
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|x64 = Debug|x64
|
||||||
Release|Any CPU = Release|Any CPU
|
Release|x64 = Release|x64
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{BC6A24FE-B35F-4F0A-8E8E-221E61E41EEF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{BC6A24FE-B35F-4F0A-8E8E-221E61E41EEF}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
{BC6A24FE-B35F-4F0A-8E8E-221E61E41EEF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{BC6A24FE-B35F-4F0A-8E8E-221E61E41EEF}.Debug|x64.Build.0 = Debug|x64
|
||||||
{BC6A24FE-B35F-4F0A-8E8E-221E61E41EEF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{BC6A24FE-B35F-4F0A-8E8E-221E61E41EEF}.Release|x64.ActiveCfg = Release|x64
|
||||||
{BC6A24FE-B35F-4F0A-8E8E-221E61E41EEF}.Release|Any CPU.Build.0 = Release|Any CPU
|
{BC6A24FE-B35F-4F0A-8E8E-221E61E41EEF}.Release|x64.Build.0 = Release|x64
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|
|
@ -88,6 +88,9 @@ body {
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
border-color: #3c6385;
|
border-color: #3c6385;
|
||||||
background-color: #375a7a;
|
background-color: #375a7a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-c3saction {
|
||||||
width: 42px !important;
|
width: 42px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue