adding summarization and restructure project

This commit is contained in:
2025-01-09 23:36:12 +01:00
parent 706ebe25a0
commit 38d4f1ad38
28 changed files with 579 additions and 209 deletions

View File

@@ -0,0 +1,17 @@
-- +goose Up
-- +goose StatementBegin
CREATE TABLE articles (
id SERIAL PRIMARY KEY,
title VARCHAR(255) NOT NULL,
sourceUrl VARCHAR(255) NOT NULL UNIQUE,
author VARCHAR(255) NOT NULL,
content TEXT NOT NULL,
publishDate TIMESTAMP NOT NULL,
fetchDate TIMESTAMP NOT NULL
);
-- +goose StatementEnd
-- +goose Down
-- +goose StatementBegin
DROP TABLE IF EXISTS articles;
-- +goose StatementEnd

View File

@@ -0,0 +1,15 @@
-- +goose Up
-- +goose StatementBegin
ALTER TABLE articles
ADD COLUMN fts_vector tsvector GENERATED ALWAYS AS (
to_tsvector('german', coalesce(title, '') || ' ' || coalesce(content, '') || ' ' || coalesce(author, ''))
) STORED;
CREATE INDEX articles_fts_idx ON articles USING gin(fts_vector);
-- +goose StatementEnd
-- +goose Down
-- +goose StatementBegin
DROP INDEX IF EXISTS articles_fts_idx;
ALTER TABLE articles DROP COLUMN IF EXISTS fts_vector;
-- +goose StatementEnd

View File

@@ -0,0 +1,13 @@
-- +goose Up
-- +goose StatementBegin
CREATE TABLE responses (
url VARCHAR(255) NOT NULL UNIQUE PRIMARY KEY,
content BYTEA NOT NULL,
fetchDate TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- +goose StatementEnd
-- +goose Down
-- +goose StatementBegin
DROP TABLE IF EXISTS responses;
-- +goose StatementEnd

View File

@@ -0,0 +1,9 @@
-- +goose Up
-- +goose StatementBegin
ALTER TABLE responses ADD COLUMN processed BOOLEAN DEFAULT false;
-- +goose StatementEnd
-- +goose Down
-- +goose StatementBegin
ALTER TABLE responses DROP COLUMN IF EXISTS processed;
-- +goose StatementEnd

View File

@@ -0,0 +1,14 @@
-- +goose Up
-- +goose StatementBegin
DROP TABLE IF EXISTS responses;
-- +goose StatementEnd
-- +goose Down
-- +goose StatementBegin
CREATE TABLE responses (
url VARCHAR(255) NOT NULL UNIQUE PRIMARY KEY,
content BYTEA NOT NULL,
fetchDate TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
processed BOOLEAN DEFAULT FALSE
);
-- +goose StatementEnd

View File

@@ -0,0 +1,36 @@
-- +goose Up
-- +goose StatementBegin
BEGIN;
DROP INDEX IF EXISTS articles_fts_idx;
ALTER TABLE articles DROP COLUMN IF EXISTS fts_vector;
ALTER TABLE articles DROP COLUMN IF EXISTS author;
ALTER TABLE articles
ADD COLUMN fts_vector tsvector GENERATED ALWAYS AS (
to_tsvector('german', coalesce(title, '') || ' ' || coalesce(content, ''))
) STORED;
CREATE INDEX articles_fts_idx ON articles USING gin(fts_vector);
COMMIT;
-- +goose StatementEnd
-- +goose Down
-- +goose StatementBegin
BEGIN;
ALTER TABLE articles ADD COLUMN author VARCHAR(255) DEFAULT '';
DROP INDEX IF EXISTS articles_fts_idx;
ALTER TABLE articles DROP COLUMN IF EXISTS fts_vector;
ALTER TABLE articles
ADD COLUMN fts_vector tsvector GENERATED ALWAYS AS (
to_tsvector('german', coalesce(title, '') || ' ' || coalesce(content, '') || ' ' || coalesce(author, ''))
) STORED;
CREATE INDEX articles_fts_idx ON articles USING gin(fts_vector);
COMMIT;
-- +goose StatementEnd

View File

@@ -0,0 +1,9 @@
-- +goose Up
-- +goose StatementBegin
ALTER TABLE articles ADD COLUMN aisummary TEXT DEFAULT '';
-- +goose StatementEnd
-- +goose Down
-- +goose StatementBegin
ALTER TABLE articles DROP COLUMN IF EXISTS aisummary;
-- +goose StatementEnd

View File

@@ -0,0 +1,75 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dark Mode Article Previews</title>
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
body {
background-color: #121212;
color: #ffffff;
}
.article-preview {
background-color: #1e1e1e;
border: 1px solid #2c2c2c;
}
a {
color: #0d6efd;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
p {
color: white
}
h5 {
color: white
}
</style>
</head>
<body>
<div class="container py-5">
<h1 class="text-center mb-auto">Article Previews</h1>
<div class="column">
<!-- Article 1 -->
<div class="col-md-6 mb-4">
<div class="card article-preview p-3">
<h5 class="card-title">Article Title 1</h5>
<p class="card-text">This is a short preview of the article content. It provides a quick summary to entice readers to click and read more.</p>
<a href="#" class="stretched-link">Read More</a>
</div>
</div>
<!-- Article 2 -->
<div class="col-md-6 mb-4">
<div class="card article-preview p-3">
<h5 class="card-title">Article Title 2</h5>
<p class="card-text">This is another preview of an article. It gives a brief overview to encourage users to explore further.</p>
<a href="#" class="stretched-link">Read More</a>
</div>
</div>
<!-- Article 3 -->
<div class="col-md-6 mb-4">
<div class="card article-preview p-3">
<h5 class="card-title">Article Title 3</h5>
<p class="card-text">A concise description of the article to pique interest and direct readers to the full content.</p>
<a href="#" class="stretched-link">Read More</a>
</div>
</div>
</div>
</div>
<!-- Bootstrap JS Bundle -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

View File

@@ -0,0 +1,22 @@
{{ define "content" }}
<div class="content container">
{{ range . }}
<div class="card p-2 m-4">
<div class="card-body">
<h5 class="card-title">{{ .Title }}</h5>
<h6 class="card-subtitle mb-2 text-body-secondary">
<span class="badge text-bg-secondary">{{ .ShortSource }}</span>
<span class="badge text-bg-secondary">{{ .PublishDate }}</span>
{{if .AiSummarized}}
<span class="badge text-bg-success">ai summary</span>
{{end}}
</h6>
<p class="card-text">{{ .Summary }}</p>
<a href="{{ .SourceUrl }}" class="card-link">Link</a>
</div>
</div>
{{ end }}
</div>
{{ end }}

View File

@@ -0,0 +1,25 @@
{{ define "base" }}
<!DOCTYPE html>
<html lang="de">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/unpoly@3.9.5/unpoly.min.css">
<body>
<nav class="navbar sticky-top bg-dark">
<div class="container-fluid">
<a class="navbar-brand text-light">crowsnest</a>
<form class="d-flex" role="search" method="post" action="/up/search" up-submit up-autosubmit up-target=".content">
<input name="search" class="form-control me-2" type="search" placeholder="Suche" aria-label="Suche">
<button class="btn btn-outline-success" type="submit">Suchen</button>
</form>
</div>
</nav>
{{ template "content" . }}
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/unpoly@3.9.5/unpoly.min.js"></script>
</body>
</html>
{{ end }}