mirror of
https://github.com/hpware/news-analyze.git
synced 2025-06-23 13:04:23 +00:00
Delete old components from a month ago? & Update draggable window to be using the native svgs by lucide icons & updated the news page to activate the tab changing animation when changing tabs & added caching into the [slug].ts file in publishers/lt & added a basic endpoint for searching for sources.
This commit is contained in:
parent
231a7ce251
commit
8032c3faae
12 changed files with 124 additions and 117 deletions
|
@ -1,5 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import { useThrottleFn } from "@vueuse/core";
|
||||
import { XIcon, MinusIcon } from "lucide-vue-next";
|
||||
|
||||
const props = defineProps<{
|
||||
title: string;
|
||||
|
@ -78,19 +79,23 @@ const stopDrag = () => {
|
|||
@mousedown="startDrag"
|
||||
class="bg-gray-700 p-2 cursor-move flex justify-between items-center flex-shrink-0 text-white z-[50] selection:opacity-0"
|
||||
>
|
||||
<h3 class="font-semibold text-white">{{ title }}</h3>
|
||||
<h3
|
||||
class="font-semibold text-white selection:opactiy-0 selection:bg-gray-700"
|
||||
>
|
||||
{{ title }}
|
||||
</h3>
|
||||
<div class="flex flex-row gap-1">
|
||||
<button
|
||||
@click="emit('min')"
|
||||
class="p-1 hover:bg-gray-300 dark:hover:bg-gray-600 rounded transition duration-200"
|
||||
>
|
||||
━
|
||||
<MinusIcon />
|
||||
</button>
|
||||
<button
|
||||
@click="emit('close')"
|
||||
class="p-1 rounded bg-red-500 text-white hover:bg-red-600 transition duration-200"
|
||||
>
|
||||
✕
|
||||
<XIcon />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -51,6 +51,7 @@ const pullTabsData = async () => {
|
|||
};
|
||||
|
||||
const updateContent = async (url: string, tabAction: boolean) => {
|
||||
contentArray.value = [];
|
||||
if (tabAction === true) {
|
||||
primary.value = url;
|
||||
switchTabs.value = true;
|
||||
|
|
|
@ -19,7 +19,7 @@ const {
|
|||
data: source,
|
||||
pending,
|
||||
error,
|
||||
} = await useFetch("/api/cached/getData/fetchSources", {
|
||||
} = await useFetch("/api/publishers/lt_all", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
|
|
|
@ -23,21 +23,6 @@ const usersList = await sql`
|
|||
)
|
||||
`;
|
||||
|
||||
const createNewsProviders = await sql`
|
||||
create table if not exists newsProviders (
|
||||
uuid text primary key,
|
||||
title text not null,
|
||||
slug text unique,
|
||||
website text not null,
|
||||
description text not null,
|
||||
facebookUrl text,
|
||||
twitterUrl text,
|
||||
threadsUrl text,
|
||||
logoUrl text not null,
|
||||
lean text not null
|
||||
)
|
||||
`;
|
||||
|
||||
const createUserAiChatHistory = await sql`
|
||||
CREATE TABLE IF NOT EXISTS chat_history (
|
||||
id SERIAL PRIMARY KEY,
|
||||
|
@ -47,38 +32,7 @@ CREATE TABLE IF NOT EXISTS chat_history (
|
|||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)`;
|
||||
|
||||
const newsArticles = await sql`
|
||||
create table if not exists news_articles (
|
||||
uuid text primary key,
|
||||
title text not null,
|
||||
content text not null,
|
||||
news_org text not null,
|
||||
origin_link text not null,
|
||||
author text,
|
||||
related_uuid text not null
|
||||
)
|
||||
`;
|
||||
|
||||
const hotNews = await sql`
|
||||
create table if not exists hot_news (
|
||||
uuid text primary key,
|
||||
title text not null,
|
||||
news_org text not null,
|
||||
link text not null,
|
||||
related_uuid text not null,
|
||||
created_at timestamptz default current_timestamp
|
||||
)
|
||||
`;
|
||||
|
||||
const articlesLt = await sql`
|
||||
create table if not exists articles_lt (
|
||||
uuid text primary key,
|
||||
title text not null,
|
||||
content text not null,
|
||||
origin text not null,
|
||||
author text
|
||||
)
|
||||
`;
|
||||
const createSources = await sql``;
|
||||
|
||||
console.log("Creation Complete");
|
||||
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
export default defineEventHandler(async (event) => {
|
||||
const slug = getRouterParam(event, "slug");
|
||||
const body = await readBody(event);
|
||||
return {
|
||||
body: body,
|
||||
title: "News Org 1",
|
||||
slug: "taisounds",
|
||||
website: "https://yuanhau.com",
|
||||
description: "wah wah wah wah wah wah I dont fucking care",
|
||||
facebook: "https://www.facebook.csdkc",
|
||||
logoUrl:
|
||||
"https://cdn.discordapp.com/avatars/918723093646684180/4eecc27ac05ee8a701fa167808610c7a.jpg",
|
||||
};
|
||||
});
|
|
@ -1,27 +0,0 @@
|
|||
import sql from "~/server/components/postgres";
|
||||
export default defineEventHandler(async (event) => {
|
||||
const body = await readBody(event);
|
||||
const query = getQuery(event);
|
||||
/*const sources = await sql`SELECT * FROM sources`;
|
||||
return sources;*/
|
||||
// Fake data
|
||||
return {
|
||||
status: "ok",
|
||||
data: [
|
||||
{
|
||||
id: 1,
|
||||
title: "Source 1",
|
||||
logo: "#",
|
||||
url: "https://source1.com",
|
||||
description: "Description for Source 1",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: "Source 2",
|
||||
logo: "#",
|
||||
url: "https://source2.com",
|
||||
description: "Description for Source 2",
|
||||
},
|
||||
],
|
||||
};
|
||||
});
|
44
server/api/create_database.ts
Normal file
44
server/api/create_database.ts
Normal file
|
@ -0,0 +1,44 @@
|
|||
import sql from "~/server/components/postgres";
|
||||
|
||||
const createUsers = await sql`
|
||||
create table if not exists users (
|
||||
uuid text primary key,
|
||||
created_at timestamptz default current_timestamp,
|
||||
username text not null unique,
|
||||
avatarurl text,
|
||||
firstname text,
|
||||
passwordhash text not null,
|
||||
email text
|
||||
);
|
||||
`;
|
||||
|
||||
const usersList = await sql`
|
||||
create table if not exists usertokens (
|
||||
token text not null primary key,
|
||||
created_at timestamptz default current_timestamp,
|
||||
username text not null,
|
||||
email text,
|
||||
avatarurl text,
|
||||
firstname text
|
||||
)
|
||||
`;
|
||||
|
||||
const createUserAiChatHistory = await sql`
|
||||
CREATE TABLE IF NOT EXISTS chat_history (
|
||||
id SERIAL PRIMARY KEY,
|
||||
uuid VARCHAR(255) NOT NULL,
|
||||
role VARCHAR(50) NOT NULL,
|
||||
content TEXT NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)`;
|
||||
|
||||
const createSources = await sql``;
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
return {
|
||||
createUsers: createUsers,
|
||||
usersList: usersList,
|
||||
createUserAiChatHistory: createUserAiChatHistory,
|
||||
createSources: createSources,
|
||||
};
|
||||
});
|
|
@ -1,10 +0,0 @@
|
|||
import s3 from "~/server/components/s3";
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const slug = getRouterParam(event, "slug");
|
||||
return sendRedirect(
|
||||
event,
|
||||
`${process.env.S3_ENDPOINT}/${process.env.S3_BUCKETNAME}/${slug}`,
|
||||
302,
|
||||
);
|
||||
});
|
|
@ -1,8 +1,43 @@
|
|||
// TODO Add caching
|
||||
import sql from "~/server/components/postgres";
|
||||
|
||||
import * as cheerio from "cheerio";
|
||||
|
||||
// Caching
|
||||
|
||||
interface CacheItems {
|
||||
slug: string;
|
||||
title: string;
|
||||
description: string;
|
||||
articles: any[];
|
||||
timestamp: number;
|
||||
}
|
||||
const CACHE_DURATION = 1000 * 60 * 30;
|
||||
const cache: Record<string, CacheItems> = {};
|
||||
|
||||
function cleanupCache() {
|
||||
const now = Date.now();
|
||||
Object.keys(cache).forEach((key) => {
|
||||
if (now - cache[key].timestamp > CACHE_DURATION) {
|
||||
delete cache[key];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
setInterval(cleanupCache, CACHE_DURATION);
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const slug = getRouterParam(event, "slug");
|
||||
if (!slug) {
|
||||
return {
|
||||
error: "NO_SLUG_PROVIDED",
|
||||
};
|
||||
}
|
||||
if (cache[slug] && Date.now() - cache[slug].timestamp < CACHE_DURATION) {
|
||||
return {
|
||||
...cache[slug],
|
||||
cached: true,
|
||||
};
|
||||
}
|
||||
const buildUrl = "https://today.line.me/tw/v3/publisher/" + slug;
|
||||
try {
|
||||
const req = await fetch(buildUrl, {
|
||||
|
@ -25,37 +60,42 @@ export default defineEventHandler(async (event) => {
|
|||
.text()
|
||||
.replace(/.css-.*\}/, "");
|
||||
const description = html("p.description").text();
|
||||
const logoClue = html("div.editor").contents();
|
||||
const logo =
|
||||
logoClue.find("img").attr("srcset") ||
|
||||
html("div.editor div figure img").attr("src") ||
|
||||
"";
|
||||
const bgImage = html("figure.keyVisual img").attr("srcset") || "";
|
||||
const articles = [];
|
||||
const regexArticleLinks = /[a-zA-Z0-9]{7}/g;
|
||||
const otherArticles = <any[]>[];
|
||||
html("a.ltcp-link").each((i, element) => {
|
||||
const articleLink = html(element).attr("href");
|
||||
const articleTitle = html(element).find("h3.header").text();
|
||||
//const image = html(element).find("figure").attr("src");
|
||||
console.log(html(element).find("img"));
|
||||
console.log("----------");
|
||||
const date = html(element)
|
||||
.find("div._articleCard div.css-wqleh6 span")
|
||||
.text();
|
||||
if (articleLink && articleTitle) {
|
||||
const articleSlug = articleLink.matchAll(regexArticleLinks);
|
||||
const articleSlug = articleLink
|
||||
.replaceAll("article", "")
|
||||
.match(regexArticleLinks);
|
||||
otherArticles.push({
|
||||
index: i,
|
||||
title: articleTitle,
|
||||
link: articleSlug,
|
||||
link: articleSlug[0],
|
||||
date: date,
|
||||
//image: image || "/geterrorassets/noImageLogo.svg",
|
||||
});
|
||||
}
|
||||
});
|
||||
cache[slug] = {
|
||||
slug: slug,
|
||||
title: newsOrgName,
|
||||
description: description,
|
||||
articles: otherArticles,
|
||||
timestamp: Date.now(),
|
||||
};
|
||||
return {
|
||||
title: newsOrgName,
|
||||
description: description,
|
||||
logo: logo,
|
||||
articles: otherArticles,
|
||||
logoClue: String(logoClue),
|
||||
cached: false,
|
||||
};
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
|
|
17
server/api/publishers/lt_all.ts
Normal file
17
server/api/publishers/lt_all.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
import sql from "~/server/components/postgres";
|
||||
export default defineEventHandler(async (event) => {
|
||||
try {
|
||||
const fetchDataInSQL = await sql`
|
||||
SELECT * FROM lt_news_org;
|
||||
`;
|
||||
return {
|
||||
data: fetchDataInSQL,
|
||||
};
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
return {
|
||||
error: "SERVER_SIDE_ERR",
|
||||
elogs: e.message,
|
||||
};
|
||||
}
|
||||
});
|
|
@ -1,3 +0,0 @@
|
|||
export default defineEventHandler(async (event) => {
|
||||
return {};
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue