Code cleanup, 2022 edition
This commit is contained in:
parent
db4a42171d
commit
1d9712294f
|
@ -1,10 +1,10 @@
|
||||||
using LinqToDB.Mapping;
|
using LinqToDB.Mapping;
|
||||||
|
|
||||||
namespace c3stream.DataModels.Tables {
|
namespace c3stream.DataModels.Tables;
|
||||||
[Table(Name = "States")]
|
|
||||||
public class States {
|
[Table(Name = "States")]
|
||||||
[Column(Name = "TalkId"), PrimaryKey, NotNull] public string TalkId { get; set; }
|
public class States {
|
||||||
[Column(Name = "UserId"), PrimaryKey, NotNull] public string UserId { get; set; }
|
[Column(Name = "TalkId"), PrimaryKey, NotNull] public string TalkId { get; set; }
|
||||||
[Column(Name = "State"), NotNull] public string State { get; set; }
|
[Column(Name = "UserId"), PrimaryKey, NotNull] public string UserId { get; set; }
|
||||||
}
|
[Column(Name = "State"), NotNull] public string State { get; set; }
|
||||||
}
|
}
|
|
@ -11,7 +11,7 @@ namespace c3stream;
|
||||||
public static class Migrations {
|
public static class Migrations {
|
||||||
private const int DbVer = 0;
|
private const int DbVer = 0;
|
||||||
|
|
||||||
private static readonly List<Migration> _migrations = new() { };
|
private static readonly List<Migration> _migrations = new();
|
||||||
|
|
||||||
public static void RunMigrations() {
|
public static void RunMigrations() {
|
||||||
using var db = new Database.DbConn();
|
using var db = new Database.DbConn();
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
@page
|
@page
|
||||||
@model ConferenceModel
|
|
||||||
@using System.Net
|
|
||||||
@using global::c3stream.DataModels
|
@using global::c3stream.DataModels
|
||||||
@using static ConferenceModel
|
@model ConferenceModel
|
||||||
@{
|
@{
|
||||||
if (c3stream.Conferences.All(c => c.Acronym != Request.Query["c"])) {
|
if (c3stream.Conferences.All(c => c.Acronym != Request.Query["c"])) {
|
||||||
Response.Redirect("/");
|
Response.Redirect("/");
|
||||||
|
|
|
@ -1,39 +1,37 @@
|
||||||
using System.Collections.Generic;
|
using System.Linq;
|
||||||
using System.Linq;
|
|
||||||
using c3stream.DataModels;
|
using c3stream.DataModels;
|
||||||
using c3stream.DataModels.Tables;
|
using c3stream.DataModels.Tables;
|
||||||
using LinqToDB;
|
using LinqToDB;
|
||||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace c3stream.Pages {
|
namespace c3stream.Pages;
|
||||||
public class ConferenceModel : PageModel {
|
|
||||||
private readonly ILogger<ConferenceModel> _logger;
|
|
||||||
|
|
||||||
public ConferenceModel(ILogger<ConferenceModel> logger) => _logger = logger;
|
public class ConferenceModel : PageModel {
|
||||||
|
private readonly ILogger<ConferenceModel> _logger;
|
||||||
|
|
||||||
public void OnGet() {
|
public ConferenceModel(ILogger<ConferenceModel> logger) => _logger = logger;
|
||||||
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;
|
|
||||||
|
|
||||||
using var db = new Database.DbConn();
|
public void OnGet() {
|
||||||
var existing = db.States.FirstOrDefault(p => p.TalkId == guid && p.UserId == userid);
|
var guid = Request.Query["guid"].ToString();
|
||||||
if (existing != null)
|
var state = Request.Query["state"].ToString();
|
||||||
if (state == "unwatched")
|
var userid = Request.Cookies["bookmark"];
|
||||||
db.States.Delete(p => p == existing);
|
if (string.IsNullOrWhiteSpace(guid) || string.IsNullOrWhiteSpace(state) || !Request.Cookies.ContainsKey("bookmark"))
|
||||||
else {
|
return;
|
||||||
existing.State = state;
|
|
||||||
db.Update(existing);
|
using var db = new Database.DbConn();
|
||||||
}
|
var existing = db.States.FirstOrDefault(p => p.TalkId == guid && p.UserId == userid);
|
||||||
else
|
if (existing != null)
|
||||||
db.Insert(new States {
|
if (state == "unwatched") {
|
||||||
State = state, TalkId = guid, UserId = userid
|
db.States.Delete(p => p == existing);
|
||||||
});
|
}
|
||||||
Response.Redirect("/");
|
else {
|
||||||
}
|
existing.State = state;
|
||||||
|
db.Update(existing);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
db.Insert(new States { State = state, TalkId = guid, UserId = userid });
|
||||||
|
|
||||||
|
Response.Redirect("/");
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,25 +1,25 @@
|
||||||
@page
|
@page
|
||||||
@model ErrorModel
|
@model ErrorModel
|
||||||
@{
|
@{
|
||||||
ViewData["Title"] = "Error";
|
ViewData["Title"] = "Error";
|
||||||
}
|
}
|
||||||
|
|
||||||
<h1 class="text-danger">Error.</h1>
|
<h1 class="text-danger">Error.</h1>
|
||||||
<h2 class="text-danger">An error occurred while processing your request.</h2>
|
<h2 class="text-danger">An error occurred while processing your request.</h2>
|
||||||
|
|
||||||
@if (Model.ShowRequestId) {
|
@if (Model.ShowRequestId) {
|
||||||
<p>
|
<p>
|
||||||
<strong>Request ID:</strong> <code>@Model.RequestId</code>
|
<strong>Request ID:</strong> <code>@Model.RequestId</code>
|
||||||
</p>
|
</p>
|
||||||
}
|
}
|
||||||
|
|
||||||
<h3>Development Mode</h3>
|
<h3>Development Mode</h3>
|
||||||
<p>
|
<p>
|
||||||
Swapping to the <strong>Development</strong> environment displays detailed information about the error that occurred.
|
Swapping to the <strong>Development</strong> environment displays detailed information about the error that occurred.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
|
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
|
||||||
It can result in displaying sensitive information from exceptions to end users.
|
It can result in displaying sensitive information from exceptions to end users.
|
||||||
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
|
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
|
||||||
and restarting the app.
|
and restarting the app.
|
||||||
</p>
|
</p>
|
|
@ -3,19 +3,19 @@ using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace c3stream.Pages {
|
namespace c3stream.Pages;
|
||||||
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
|
|
||||||
public class ErrorModel : PageModel {
|
|
||||||
private readonly ILogger<ErrorModel> _logger;
|
|
||||||
|
|
||||||
public ErrorModel(ILogger<ErrorModel> logger) => _logger = logger;
|
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
|
||||||
|
public class ErrorModel : PageModel {
|
||||||
|
private readonly ILogger<ErrorModel> _logger;
|
||||||
|
|
||||||
public string RequestId { get; set; }
|
public ErrorModel(ILogger<ErrorModel> logger) => _logger = logger;
|
||||||
|
|
||||||
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
|
public string RequestId { get; set; }
|
||||||
|
|
||||||
public void OnGet() {
|
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
|
||||||
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
|
|
||||||
}
|
public void OnGet() {
|
||||||
|
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,12 +1,12 @@
|
||||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace c3stream.Pages {
|
namespace c3stream.Pages;
|
||||||
public class IndexModel : PageModel {
|
|
||||||
private readonly ILogger<IndexModel> _logger;
|
|
||||||
|
|
||||||
public IndexModel(ILogger<IndexModel> logger) => _logger = logger;
|
public class IndexModel : PageModel {
|
||||||
|
private readonly ILogger<IndexModel> _logger;
|
||||||
|
|
||||||
public void OnGet() { }
|
public IndexModel(ILogger<IndexModel> logger) => _logger = logger;
|
||||||
}
|
|
||||||
|
public void OnGet() { }
|
||||||
}
|
}
|
|
@ -2,115 +2,115 @@
|
||||||
@using global::c3stream.DataModels
|
@using global::c3stream.DataModels
|
||||||
@model InfoModel
|
@model InfoModel
|
||||||
@{
|
@{
|
||||||
ViewData["Title"] = "Info";
|
ViewData["Title"] = "Info";
|
||||||
}
|
}
|
||||||
@{
|
@{
|
||||||
if (string.IsNullOrWhiteSpace(Request.Query["guid"]) || c3stream.GetEventByGuid(Request.Query["guid"]) == null) {
|
if (string.IsNullOrWhiteSpace(Request.Query["guid"]) || c3stream.GetEventByGuid(Request.Query["guid"]) == null) {
|
||||||
Response.Redirect("/");
|
Response.Redirect("/");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var cookie = c3stream.UpdateCookie(Request, Response, $"/Info?guid={Request.Query["guid"]}");
|
var cookie = c3stream.UpdateCookie(Request, Response, $"/Info?guid={Request.Query["guid"]}");
|
||||||
|
|
||||||
await using var db = new Database.DbConn();
|
|
||||||
|
|
||||||
var talk = c3stream.GetEventByGuid(Request.Query["guid"]);
|
await using var db = new Database.DbConn();
|
||||||
var state = db.States.FirstOrDefault(p => p.TalkId == Request.Query["guid"].ToString() && p.UserId == cookie)?.State;
|
|
||||||
if (talk == null) {
|
|
||||||
Response.Redirect("/");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (state == null) {
|
|
||||||
state = "unwatched";
|
|
||||||
}
|
|
||||||
|
|
||||||
var title = talk.Title;
|
var talk = c3stream.GetEventByGuid(Request.Query["guid"]);
|
||||||
var speakers = talk.Persons.Any() ? talk.Persons.Aggregate((s, s1) => $"{s}, {s1}") : "<no speakers>";
|
var state = db.States.FirstOrDefault(p => p.TalkId == Request.Query["guid"].ToString() && p.UserId == cookie)?.State;
|
||||||
var description = talk.Description;
|
if (talk == null) {
|
||||||
if (string.IsNullOrEmpty(description)) {
|
Response.Redirect("/");
|
||||||
description = "<missing description>";
|
return;
|
||||||
}
|
}
|
||||||
|
if (state == null) {
|
||||||
|
state = "unwatched";
|
||||||
|
}
|
||||||
|
|
||||||
var isWatched = state == "watched";
|
var title = talk.Title;
|
||||||
var isMarked = state == "marked";
|
var speakers = talk.Persons.Any() ? talk.Persons.Aggregate((s, s1) => $"{s}, {s1}") : "<no speakers>";
|
||||||
var file = $"{talk.Slug}.mp4";
|
var description = talk.Description;
|
||||||
var conference = c3stream.GetConferenceByEventGuid(talk.Guid);
|
if (string.IsNullOrEmpty(description)) {
|
||||||
|
description = "<missing description>";
|
||||||
|
}
|
||||||
|
|
||||||
var eventName = talk.Tags.Count <= 1 ? conference.Acronym : talk.Tags[0];
|
var isWatched = state == "watched";
|
||||||
var logoPath = System.IO.Path.Combine(c3stream.CachePath, conference.Acronym, "logo.png");
|
var isMarked = state == "marked";
|
||||||
|
var file = $"{talk.Slug}.mp4";
|
||||||
|
var conference = c3stream.GetConferenceByEventGuid(talk.Guid);
|
||||||
|
|
||||||
var category = talk.Tags.Count switch {
|
var eventName = talk.Tags.Count <= 1 ? conference.Acronym : talk.Tags[0];
|
||||||
0 => "<no category>",
|
var logoPath = System.IO.Path.Combine(c3stream.CachePath, conference.Acronym, "logo.png");
|
||||||
1 => talk.Tags[0],
|
|
||||||
2 => "<no category>",
|
var category = talk.Tags.Count switch {
|
||||||
3 => talk.Tags[2],
|
0 => "<no category>",
|
||||||
4 => talk.Tags[3],
|
1 => talk.Tags[0],
|
||||||
5 => talk.Tags[3],
|
2 => "<no category>",
|
||||||
6 => talk.Tags[3], // rc3: is this correct?
|
3 => talk.Tags[2],
|
||||||
_ => "<unknown tag format>"
|
4 => talk.Tags[3],
|
||||||
};
|
5 => talk.Tags[3],
|
||||||
|
6 => talk.Tags[3], // rc3: is this correct?
|
||||||
|
_ => "<unknown tag format>"
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (System.IO.File.Exists(logoPath)) {
|
@if (System.IO.File.Exists(logoPath)) {
|
||||||
<img src="@(c3stream.CacheUrl + $"{conference.Acronym}/logo.png")" alt="Conference logo" style="max-height: 110px; float: right;"/>
|
<img src="@(c3stream.CacheUrl + $"{conference.Acronym}/logo.png")" alt="Conference logo" style="max-height: 110px; float: right;"/>
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
<img src="@conference.LogoUri" alt="Conference logo" style="max-height: 110px; float: right;"/>
|
<img src="@conference.LogoUri" alt="Conference logo" style="max-height: 110px; float: right;"/>
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (isWatched) {
|
@if (isWatched) {
|
||||||
<h3 style="color: #95cb7a">@title - <i>@speakers</i></h3>
|
<h3 style="color: #95cb7a">@title - <i>@speakers</i></h3>
|
||||||
}
|
}
|
||||||
else if (isMarked) {
|
else if (isMarked) {
|
||||||
<h3 style="color: #da7d4f">@title - <i>@speakers</i></h3>
|
<h3 style="color: #da7d4f">@title - <i>@speakers</i></h3>
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
<h3>@title - <i>@speakers</i></h3>
|
<h3>@title - <i>@speakers</i></h3>
|
||||||
}
|
}
|
||||||
|
|
||||||
<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 btn-c3saction 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 btn-c3saction 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 btn-c3saction 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 btn-c3saction 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 btn-c3saction 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 btn-c3saction 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 btn-c3saction 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 btn-c3saction 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 btn-c3saction 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>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p style="text-align: justify">
|
<p style="text-align: justify">
|
||||||
@Html.Raw(description.Replace("\n", "<br/>").Replace("<p>", "").Replace("</p>", ""))
|
@Html.Raw(description.Replace("\n", "<br/>").Replace("<p>", "").Replace("</p>", ""))
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
Share this talk:<br/>
|
Share this talk:<br/>
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace c3stream.Pages {
|
namespace c3stream.Pages;
|
||||||
public class InfoModel : PageModel {
|
|
||||||
private readonly ILogger<InfoModel> _logger;
|
|
||||||
|
|
||||||
public InfoModel(ILogger<InfoModel> logger) => _logger = logger;
|
public class InfoModel : PageModel {
|
||||||
|
private readonly ILogger<InfoModel> _logger;
|
||||||
|
|
||||||
public void OnGet() { }
|
public InfoModel(ILogger<InfoModel> logger) => _logger = logger;
|
||||||
}
|
|
||||||
|
public void OnGet() { }
|
||||||
}
|
}
|
|
@ -1,12 +1,12 @@
|
||||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace c3stream.Pages {
|
namespace c3stream.Pages;
|
||||||
public class PrivacyModel : PageModel {
|
|
||||||
private readonly ILogger<PrivacyModel> _logger;
|
|
||||||
|
|
||||||
public PrivacyModel(ILogger<PrivacyModel> logger) => _logger = logger;
|
public class PrivacyModel : PageModel {
|
||||||
|
private readonly ILogger<PrivacyModel> _logger;
|
||||||
|
|
||||||
public void OnGet() { }
|
public PrivacyModel(ILogger<PrivacyModel> logger) => _logger = logger;
|
||||||
}
|
|
||||||
|
public void OnGet() { }
|
||||||
}
|
}
|
|
@ -1,38 +1,38 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8"/>
|
<meta charset="utf-8"/>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
<title>@ViewData["Title"] - c3stream</title>
|
<title>@ViewData["Title"] - c3stream</title>
|
||||||
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css"/>
|
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css"/>
|
||||||
<link rel="stylesheet" href="~/css/fa.css" crossorigin="anonymous">
|
<link rel="stylesheet" href="~/css/fa.css" crossorigin="anonymous">
|
||||||
<link rel="stylesheet" href="~/css/site.css"/>
|
<link rel="stylesheet" href="~/css/site.css"/>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
|
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
|
||||||
<div class="container-fluid" style="width: 90%">
|
<div class="container-fluid" style="width: 90%">
|
||||||
<a class="navbar-brand" asp-area="" asp-page="/Index">c3stream <small style="font-size: x-small">v5</small></a>
|
<a class="navbar-brand" asp-area="" asp-page="/Index">c3stream <small style="font-size: x-small">v5</small></a>
|
||||||
<button class="navbar-toggler" role="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
|
<button class="navbar-toggler" role="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
|
||||||
aria-expanded="false" aria-label="Toggle navigation">
|
aria-expanded="false" aria-label="Toggle navigation">
|
||||||
<span class="navbar-toggler-icon"></span>
|
<span class="navbar-toggler-icon"></span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
<div class="container-fluid" style="width: 90%">
|
<div class="container-fluid" style="width: 90%">
|
||||||
<main role="main" class="pb-3">
|
<main role="main" class="pb-3">
|
||||||
@RenderBody()
|
@RenderBody()
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<footer class="border-top footer">
|
<footer class="border-top footer">
|
||||||
<div class="container-fluid" style="width: 90%; text-align: center">
|
<div class="container-fluid" style="width: 90%; text-align: center">
|
||||||
<a href="/Privacy">Privacy</a> -
|
<a href="/Privacy">Privacy</a> -
|
||||||
<a href="mailto:c3stream-contact@zotan.email">Contact</a> -
|
<a href="mailto:c3stream-contact@zotan.email">Contact</a> -
|
||||||
<a href="https://git.zotan.services/zotan/c3stream/">Source Code</a> -
|
<a href="https://git.zotan.services/zotan/c3stream/">Source Code</a> -
|
||||||
c3stream is not affiliated with media.ccc.de in any way. Mirrored video files display their license in the video, no rights reserved.
|
c3stream is not affiliated with media.ccc.de in any way. Mirrored video files display their license in the video, no rights reserved.
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
<script src="~/lib/jquery/dist/jquery.min.js"></script>
|
<script src="~/lib/jquery/dist/jquery.min.js"></script>
|
||||||
|
@ -41,4 +41,4 @@
|
||||||
|
|
||||||
@RenderSection("Scripts", false)
|
@RenderSection("Scripts", false)
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -1,10 +1,8 @@
|
||||||
@page
|
@page
|
||||||
@model WatchlistModel
|
|
||||||
@using System.Net
|
|
||||||
@using global::c3stream.DataModels
|
@using global::c3stream.DataModels
|
||||||
@using static WatchlistModel
|
@model WatchlistModel
|
||||||
@{
|
@{
|
||||||
var cookie = c3stream.UpdateCookie(Request, Response, $"/Watchlist");
|
var cookie = c3stream.UpdateCookie(Request, Response, "/Watchlist");
|
||||||
ViewData["Title"] = "Watchlist";
|
ViewData["Title"] = "Watchlist";
|
||||||
await using var db = new Database.DbConn();
|
await using var db = new Database.DbConn();
|
||||||
var states = db.States.ToList();
|
var states = db.States.ToList();
|
||||||
|
|
|
@ -1,39 +1,37 @@
|
||||||
using System.Collections.Generic;
|
using System.Linq;
|
||||||
using System.Linq;
|
|
||||||
using c3stream.DataModels;
|
using c3stream.DataModels;
|
||||||
using c3stream.DataModels.Tables;
|
using c3stream.DataModels.Tables;
|
||||||
using LinqToDB;
|
using LinqToDB;
|
||||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace c3stream.Pages {
|
namespace c3stream.Pages;
|
||||||
public class WatchlistModel : PageModel {
|
|
||||||
private readonly ILogger<ConferenceModel> _logger;
|
|
||||||
|
|
||||||
public WatchlistModel(ILogger<ConferenceModel> logger) => _logger = logger;
|
public class WatchlistModel : PageModel {
|
||||||
|
private readonly ILogger<ConferenceModel> _logger;
|
||||||
|
|
||||||
public void OnGet() {
|
public WatchlistModel(ILogger<ConferenceModel> logger) => _logger = logger;
|
||||||
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;
|
|
||||||
|
|
||||||
using var db = new Database.DbConn();
|
public void OnGet() {
|
||||||
var existing = db.States.FirstOrDefault(p => p.TalkId == guid && p.UserId == userid);
|
var guid = Request.Query["guid"].ToString();
|
||||||
if (existing != null)
|
var state = Request.Query["state"].ToString();
|
||||||
if (state == "unwatched")
|
var userid = Request.Cookies["bookmark"];
|
||||||
db.States.Delete(p => p == existing);
|
if (string.IsNullOrWhiteSpace(guid) || string.IsNullOrWhiteSpace(state) || !Request.Cookies.ContainsKey("bookmark"))
|
||||||
else {
|
return;
|
||||||
existing.State = state;
|
|
||||||
db.Update(existing);
|
using var db = new Database.DbConn();
|
||||||
}
|
var existing = db.States.FirstOrDefault(p => p.TalkId == guid && p.UserId == userid);
|
||||||
else
|
if (existing != null)
|
||||||
db.Insert(new States {
|
if (state == "unwatched") {
|
||||||
State = state, TalkId = guid, UserId = userid
|
db.States.Delete(p => p == existing);
|
||||||
});
|
}
|
||||||
Response.Redirect("/");
|
else {
|
||||||
}
|
existing.State = state;
|
||||||
|
db.Update(existing);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
db.Insert(new States { State = state, TalkId = guid, UserId = userid });
|
||||||
|
|
||||||
|
Response.Redirect("/");
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,3 +1,3 @@
|
||||||
@{
|
@{
|
||||||
Layout = "_Layout";
|
Layout = "_Layout";
|
||||||
}
|
}
|
|
@ -1 +1,2 @@
|
||||||
c3stream is a small proxy site meant for saving watched status & watch-later-lists for media.ccc.de talks. Test in production at https://c3stream.de
|
c3stream is a small proxy site meant for saving watched status & watch-later-lists for media.ccc.de talks. Test in
|
||||||
|
production at https://c3stream.de
|
40
Startup.cs
40
Startup.cs
|
@ -4,32 +4,32 @@ using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
|
|
||||||
namespace c3stream {
|
namespace c3stream;
|
||||||
public class Startup {
|
|
||||||
public Startup(IConfiguration configuration) => Configuration = configuration;
|
|
||||||
|
|
||||||
public IConfiguration Configuration { get; }
|
public class Startup {
|
||||||
|
public Startup(IConfiguration configuration) => Configuration = configuration;
|
||||||
|
|
||||||
// This method gets called by the runtime. Use this method to add services to the container.
|
public IConfiguration Configuration { get; }
|
||||||
public void ConfigureServices(IServiceCollection services) {
|
|
||||||
services.AddRazorPages();
|
|
||||||
}
|
|
||||||
|
|
||||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
// This method gets called by the runtime. Use this method to add services to the container.
|
||||||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) {
|
public void ConfigureServices(IServiceCollection services) {
|
||||||
if (env.IsDevelopment())
|
services.AddRazorPages();
|
||||||
app.UseDeveloperExceptionPage();
|
}
|
||||||
else
|
|
||||||
app.UseExceptionHandler("/Error");
|
|
||||||
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
|
|
||||||
|
|
||||||
app.UseStaticFiles();
|
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||||
|
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) {
|
||||||
|
if (env.IsDevelopment())
|
||||||
|
app.UseDeveloperExceptionPage();
|
||||||
|
else
|
||||||
|
app.UseExceptionHandler("/Error");
|
||||||
|
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
|
||||||
|
|
||||||
app.UseRouting();
|
app.UseStaticFiles();
|
||||||
|
|
||||||
app.UseAuthorization();
|
app.UseRouting();
|
||||||
|
|
||||||
app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); });
|
app.UseAuthorization();
|
||||||
}
|
|
||||||
|
app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); });
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue