aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--I2R.LightNews.sln22
-rw-r--r--src/Pages/Index.cshtml6
-rw-r--r--src/Pages/Read.cshtml17
-rw-r--r--src/Pages/Read.cshtml.cs2
-rw-r--r--src/Pages/Shared/_Layout.cshtml1
-rw-r--r--src/Services/GrabberService.cs93
-rw-r--r--src/wwwroot/index.css91
-rw-r--r--src/wwwroot/reset.css74
8 files changed, 176 insertions, 130 deletions
diff --git a/I2R.LightNews.sln b/I2R.LightNews.sln
new file mode 100644
index 0000000..49b242c
--- /dev/null
+++ b/I2R.LightNews.sln
@@ -0,0 +1,22 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.31903.59
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "I2R.LightNews", "src\I2R.LightNews.csproj", "{B302C2CC-E18F-460A-8BDA-2EC59F73F33C}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {B302C2CC-E18F-460A-8BDA-2EC59F73F33C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B302C2CC-E18F-460A-8BDA-2EC59F73F33C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B302C2CC-E18F-460A-8BDA-2EC59F73F33C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B302C2CC-E18F-460A-8BDA-2EC59F73F33C}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+EndGlobal
diff --git a/src/Pages/Index.cshtml b/src/Pages/Index.cshtml
index d809043..f01b263 100644
--- a/src/Pages/Index.cshtml
+++ b/src/Pages/Index.cshtml
@@ -5,11 +5,11 @@
}
@foreach (var article in Model.Source.Articles) {
- <section style="margin-bottom: 8px;display: flex; flex-direction: column">
+ <section class="news-link">
<a href="/les/@Model.Source.Name?url=@article.Href">
- <h2 style="font-size: 18px">@Html.Raw(article.Title)</h2>
+ <h2>@Html.Raw(article.Title)</h2>
</a>
- <a href="@article.Href" style="font-size: 14px;display:flex;justify-content: end" rel="noreferrer">Les på nrk.no</a>
+ <a href="@article.Href" class="source-link" rel="noreferrer">Les på nrk.no</a>
</section>
}
<footer>
diff --git a/src/Pages/Read.cshtml b/src/Pages/Read.cshtml
index 63543aa..9cff853 100644
--- a/src/Pages/Read.cshtml
+++ b/src/Pages/Read.cshtml
@@ -11,9 +11,10 @@
</div>
</div>
-<div id="art-body">
+<article id="art-body">
@Html.Raw(Model.Source.Content)
-</div>
+</article>
+
<footer>
<p>
<div style="display: flex; flex-direction: column; flex-wrap: nowrap;">
@@ -33,9 +34,17 @@
}
<br/>
<small>
- <a href="@Model.Source.Href">Les på nrk.no</a>
+ <a href="@Model.Source.Href" no-interception>Les på nrk.no</a>
</small>
</div>
</div>
</p>
-</footer> \ No newline at end of file
+</footer>
+
+<script>
+document.addEventListener("DOMContentLoaded", () => {
+ document.querySelectorAll("a:not([no-interception])").forEach(el => {
+ if (el.href.indexOf("nrk.no") !== -1) el.href = "/les/nrk?url=" + el.href;
+ });
+})
+</script> \ No newline at end of file
diff --git a/src/Pages/Read.cshtml.cs b/src/Pages/Read.cshtml.cs
index 16a1055..1a13ec0 100644
--- a/src/Pages/Read.cshtml.cs
+++ b/src/Pages/Read.cshtml.cs
@@ -18,7 +18,7 @@ public class ReadModel : PageModel
"nrk" => await _grabber.GrabNrkArticleAsync(url),
_ => default
};
- if (Source == default) return Redirect("/");
+ if (Source == default) return Redirect(url);
return Page();
}
} \ No newline at end of file
diff --git a/src/Pages/Shared/_Layout.cshtml b/src/Pages/Shared/_Layout.cshtml
index 7831774..09babeb 100644
--- a/src/Pages/Shared/_Layout.cshtml
+++ b/src/Pages/Shared/_Layout.cshtml
@@ -3,7 +3,6 @@
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
- <link rel="stylesheet" href="/reset.css">
<link rel="stylesheet" href="/index.css">
<title>@ViewData["Title"] - Lettnytt</title>
</head>
diff --git a/src/Services/GrabberService.cs b/src/Services/GrabberService.cs
index 3974a9e..4886023 100644
--- a/src/Services/GrabberService.cs
+++ b/src/Services/GrabberService.cs
@@ -44,56 +44,59 @@ public class GrabberService
using var md5 = MD5.Create();
var articleFilePrefix = "art-" + NrkPrefix + "-" + Convert.ToHexString(md5.ComputeHash(Encoding.UTF8.GetBytes(url)));
return await _memoryCache.GetOrCreateAsync(articleFilePrefix, async entry => {
- entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(10);
- var source = await GrabSourceAsync(url, articleFilePrefix);
- var parser = new HtmlParser();
- var doc = await parser.ParseDocumentAsync(source.Content);
- var result = new NewsArticle() {
- CachedAt = source.CacheFileCreatedAt,
- Href = url,
- Title = doc.QuerySelector("h1.title")?.TextContent,
- Subtitle = doc.QuerySelector(".article-lead p")?.TextContent,
- Authors = new List<NewsArticle.Author>()
- };
-
- foreach (var authorNode in doc.QuerySelectorAll(".authors .author")) {
- var author = new NewsArticle.Author() {
- Name = authorNode.QuerySelector(".author__name")?.TextContent,
- Title = authorNode.QuerySelector(".author__role")?.TextContent
+ entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(10);
+ var source = await GrabSourceAsync(url, articleFilePrefix);
+ var parser = new HtmlParser();
+ var doc = await parser.ParseDocumentAsync(source.Content);
+ var result = new NewsArticle() {
+ CachedAt = source.CacheFileCreatedAt,
+ Href = url,
+ Title = doc.QuerySelector("h1.title")?.TextContent,
+ Subtitle = doc.QuerySelector(".article-lead p")?.TextContent,
+ Authors = new List<NewsArticle.Author>()
};
- result.Authors.Add(author);
- }
- DateTime.TryParse(doc.QuerySelector("time.datePublished")?.Attributes["datetime"]?.Value, out var published);
- DateTime.TryParse(doc.QuerySelector("time.dateModified")?.Attributes["datetime"]?.Value, out var modified);
+ foreach (var authorNode in doc.QuerySelectorAll(".authors .author")) {
+ var author = new NewsArticle.Author() {
+ Name = authorNode.QuerySelector(".author__name")?.TextContent,
+ Title = authorNode.QuerySelector(".author__role")?.TextContent
+ };
+ result.Authors.Add(author);
+ }
- result.UpdatedAt = modified;
- result.PublishedAt = published;
+ DateTime.TryParse(doc.QuerySelector("time.datePublished")?.Attributes["datetime"]?.Value, out var published);
+ DateTime.TryParse(doc.QuerySelector("time.dateModified")?.Attributes["datetime"]?.Value, out var modified);
- if (doc.QuerySelector("kortstokk-app") != default) {
- var excludes = new List<string>() {
- ".dhks-background",
- ".dhks-actions",
- ".dhks-credits",
- ".dhks-sticky-reset",
- ".dhks-byline"
- };
- result.Content = HtmlSanitiser.SanitizeHtmlFragment(doc.QuerySelector(".dhks-cardSection").InnerHtml, string.Join(',', excludes));
- } else {
- var excludes = new List<string>() {
- ".compilation-reference",
- ".section-reference",
- ".widget",
- ".image-reference",
- ".video-reference",
- ".article-body--updating",
- ".reference"
- };
- result.Content = HtmlSanitiser.SanitizeHtmlFragment(doc.QuerySelector(".article-body").InnerHtml, string.Join(',', excludes));
- }
+ result.UpdatedAt = modified;
+ result.PublishedAt = published;
- return result;
- });
+ if (doc.QuerySelector("kortstokk-app") != default) {
+ var excludes = new List<string>() {
+ ".dhks-background",
+ ".dhks-actions",
+ ".dhks-credits",
+ ".dhks-sticky-reset",
+ ".dhks-byline"
+ };
+ result.Content = HtmlSanitiser.SanitizeHtmlFragment(doc.QuerySelector(".dhks-cardSection").InnerHtml, string.Join(',', excludes));
+ } else if (url.Contains("nrk.no/nyheter")) {
+ result.Content = HtmlSanitiser.SanitizeHtmlFragment(doc.QuerySelector(".bulletin-text").InnerHtml);
+ } else {
+ var excludes = new List<string>() {
+ ".compilation-reference",
+ ".section-reference",
+ ".widget",
+ ".image-reference",
+ ".video-reference",
+ ".article-body--updating",
+ ".reference"
+ };
+ result.Content = HtmlSanitiser.SanitizeHtmlFragment(doc.QuerySelector(".article-body").InnerHtml, string.Join(',', excludes));
+ }
+
+ return result;
+ })
+ ;
}
public async Task<NewsSource> GrabNrkAsync() {
diff --git a/src/wwwroot/index.css b/src/wwwroot/index.css
index 0296036..2c5ac3f 100644
--- a/src/wwwroot/index.css
+++ b/src/wwwroot/index.css
@@ -1,10 +1,81 @@
+/* Box sizing rules */
+*,
+*::before,
+*::after {
+ box-sizing: border-box;
+}
+
+/* Remove default margin */
+body,
+h1,
+h2,
+h3,
+h4,
+p,
+a,
+figure,
+blockquote,
+dl,
+dd {
+ margin: 0;
+}
+
+/* Remove list styles on ul, ol elements with a list role, which suggests default styling will be removed */
+ul[role="list"],
+ol[role="list"] {
+ list-style: none;
+}
+
+/* Set core root defaults */
+html:focus-within {
+ scroll-behavior: smooth;
+}
+
+/* A elements that don't have a class get default styles */
+a:not([class]) {
+ text-decoration-skip-ink: auto;
+}
+
+/* Make images easier to work with */
+img,
+picture {
+ max-width: 100%;
+ display: block;
+}
+
+/* Inherit fonts for inputs and buttons */
+input,
+button,
+textarea,
+select {
+ font: inherit;
+}
+
+/* Remove all animations and transitions for people that prefer not to see them */
+@media (prefers-reduced-motion: reduce) {
+ html:focus-within {
+ scroll-behavior: auto;
+ }
+
+ *,
+ *::before,
+ *::after {
+ animation-duration: 0.01ms !important;
+ animation-iteration-count: 1 !important;
+ transition-duration: 0.01ms !important;
+ scroll-behavior: auto !important;
+ }
+}
+
+
body {
+ min-height: 100vh;
+ text-rendering: optimizeSpeed;
+ line-height: 1.5;
display: flex;
flex-direction: column;
- min-height: 100vh;
padding: 5vh clamp(1rem, 5vw, 3rem) 1rem;
font-family: system-ui, sans-serif;
- line-height: 1.5;
color: #222;
background: white;
}
@@ -53,4 +124,20 @@ article * + * {
.quote-source {
padding-left: 20px;
+}
+
+.news-link {
+ margin-bottom: 8px;
+ display: flex;
+ flex-direction: column
+}
+
+.news-link h2 {
+ font-size: 18px;
+}
+
+.news-link .source-link {
+ font-size: 14px;
+ display: flex;
+ justify-content: end
} \ No newline at end of file
diff --git a/src/wwwroot/reset.css b/src/wwwroot/reset.css
deleted file mode 100644
index ae5fad7..0000000
--- a/src/wwwroot/reset.css
+++ /dev/null
@@ -1,74 +0,0 @@
-/* Box sizing rules */
-*,
-*::before,
-*::after {
- box-sizing: border-box;
-}
-
-/* Remove default margin */
-body,
-h1,
-h2,
-h3,
-h4,
-p,
-figure,
-blockquote,
-dl,
-dd {
- margin: 0;
-}
-
-/* Remove list styles on ul, ol elements with a list role, which suggests default styling will be removed */
-ul[role="list"],
-ol[role="list"] {
- list-style: none;
-}
-
-/* Set core root defaults */
-html:focus-within {
- scroll-behavior: smooth;
-}
-
-/* Set core body defaults */
-body {
- min-height: 100vh;
- text-rendering: optimizeSpeed;
- line-height: 1.5;
-}
-
-/* A elements that don't have a class get default styles */
-a:not([class]) {
- text-decoration-skip-ink: auto;
-}
-
-/* Make images easier to work with */
-img,
-picture {
- max-width: 100%;
- display: block;
-}
-
-/* Inherit fonts for inputs and buttons */
-input,
-button,
-textarea,
-select {
- font: inherit;
-}
-
-/* Remove all animations and transitions for people that prefer not to see them */
-@media (prefers-reduced-motion: reduce) {
- html:focus-within {
- scroll-behavior: auto;
- }
-
- *,
- *::before,
- *::after {
- animation-duration: 0.01ms !important;
- animation-iteration-count: 1 !important;
- transition-duration: 0.01ms !important;
- scroll-behavior: auto !important;
- }
-}