Fix a bug with forms, etc. Added normal toggling of themes. Started building the news parser
This commit is contained in:
parent
b47fe4917e
commit
79abcb348f
@ -40,11 +40,19 @@
|
|||||||
background-color: rgba(55, 55, 55, 0.45) !important;
|
background-color: rgba(55, 55, 55, 0.45) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#app {
|
html, body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
bottom: 0;
|
width: 100%;
|
||||||
width: 100vw;
|
min-height: 100%;
|
||||||
height: 100vh;
|
}
|
||||||
|
|
||||||
|
#app {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
padding-bottom: 80px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.news-ui-action {
|
.news-ui-action {
|
||||||
@ -61,8 +69,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.auth-card {
|
.auth-card {
|
||||||
margin-left: 30vw;
|
width: min(430px, calc(100vw - 32px));
|
||||||
margin-right: 30vw;
|
margin: 0;
|
||||||
margin-top: 30vh;
|
|
||||||
margin-bottom: 30vh;
|
|
||||||
}
|
}
|
||||||
@ -81,8 +81,7 @@ async function main() {
|
|||||||
});
|
});
|
||||||
appElement.style = currentStyle;
|
appElement.style = currentStyle;
|
||||||
|
|
||||||
//document.body.innerHTML = appElement.build() + navbar.build();
|
document.body.innerHTML = appElement.build() + navbar.build();
|
||||||
document.body.innerHTML = appElement.build();
|
|
||||||
await changeStyleLogic(appElement, navbar);
|
await changeStyleLogic(appElement, navbar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
export interface Source {
|
export interface NewsSource {
|
||||||
name: string,
|
name: string,
|
||||||
icon?: string,
|
icon?: string,
|
||||||
sourceURL?: string,
|
sourceURL?: string,
|
||||||
|
type: "RSS",
|
||||||
itemURL?: string,
|
itemURL?: string,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9,6 +10,6 @@ export interface NewsItem {
|
|||||||
id : number;
|
id : number;
|
||||||
title : string;
|
title : string;
|
||||||
content : string;
|
content : string;
|
||||||
source: Source;
|
source: NewsSource;
|
||||||
publishedAt : Date;
|
publishedAt : Date;
|
||||||
}
|
}
|
||||||
@ -16,7 +16,7 @@ declare module 'express-serve-static-core' {
|
|||||||
// Checking auth
|
// Checking auth
|
||||||
app.use((req, res, next) => {
|
app.use((req, res, next) => {
|
||||||
req.authenticationRules = { type: "password" };
|
req.authenticationRules = { type: "password" };
|
||||||
req.isAuthenticated = false; // Mock authentication, replace with real logic
|
req.isAuthenticated = true; // Mock authentication, replace with real logic
|
||||||
// Add your authentication logic here
|
// Add your authentication logic here
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
|
|||||||
3
src/utils/database/index.ts
Normal file
3
src/utils/database/index.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
class Database {}
|
||||||
|
|
||||||
|
export = new Database;
|
||||||
@ -1,4 +1,4 @@
|
|||||||
import { NewsItem } from "../api/models/news";
|
import { NewsItem } from "../../api/models/news";
|
||||||
|
|
||||||
export function getTestNews (): NewsItem[] {
|
export function getTestNews (): NewsItem[] {
|
||||||
console.warn("Remove getTestNews from production! Only for tests!");
|
console.warn("Remove getTestNews from production! Only for tests!");
|
||||||
@ -10,7 +10,8 @@ export function getTestNews (): NewsItem[] {
|
|||||||
content: "Lorem Ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet,",
|
content: "Lorem Ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet,",
|
||||||
publishedAt: new Date(),
|
publishedAt: new Date(),
|
||||||
source: {
|
source: {
|
||||||
name: "Test Destination"
|
name: "Test Destination",
|
||||||
|
type: "RSS",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -19,7 +20,8 @@ export function getTestNews (): NewsItem[] {
|
|||||||
content: "This is the content for news item 1. It contains some sample text to demonstrate the news functionality.",
|
content: "This is the content for news item 1. It contains some sample text to demonstrate the news functionality.",
|
||||||
publishedAt: new Date(),
|
publishedAt: new Date(),
|
||||||
source: {
|
source: {
|
||||||
name: "Test Destination"
|
name: "Test Destination",
|
||||||
|
type: "RSS",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -28,7 +30,8 @@ export function getTestNews (): NewsItem[] {
|
|||||||
content: "This is the content for news item 2. Another piece of sample news content for testing purposes.",
|
content: "This is the content for news item 2. Another piece of sample news content for testing purposes.",
|
||||||
publishedAt: new Date(),
|
publishedAt: new Date(),
|
||||||
source: {
|
source: {
|
||||||
name: "Test Destination"
|
name: "Test Destination",
|
||||||
|
type: "RSS",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -37,7 +40,8 @@ export function getTestNews (): NewsItem[] {
|
|||||||
content: "News item 3 brings you the latest updates. Stay informed with our regular news feed.",
|
content: "News item 3 brings you the latest updates. Stay informed with our regular news feed.",
|
||||||
publishedAt: new Date(),
|
publishedAt: new Date(),
|
||||||
source: {
|
source: {
|
||||||
name: "Test Destination"
|
name: "Test Destination",
|
||||||
|
type: "RSS",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -46,7 +50,8 @@ export function getTestNews (): NewsItem[] {
|
|||||||
content: "Content for the fourth news item. This is part of the test data for the application.",
|
content: "Content for the fourth news item. This is part of the test data for the application.",
|
||||||
publishedAt: new Date(),
|
publishedAt: new Date(),
|
||||||
source: {
|
source: {
|
||||||
name: "Test Destination"
|
name: "Test Destination",
|
||||||
|
type: "RSS",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -55,7 +60,8 @@ export function getTestNews (): NewsItem[] {
|
|||||||
content: "Fifth news item in the list. More sample content to populate the news array.",
|
content: "Fifth news item in the list. More sample content to populate the news array.",
|
||||||
publishedAt: new Date(),
|
publishedAt: new Date(),
|
||||||
source: {
|
source: {
|
||||||
name: "Test Destination"
|
name: "Test Destination",
|
||||||
|
type: "RSS",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -64,7 +70,8 @@ export function getTestNews (): NewsItem[] {
|
|||||||
content: "This is news item number six. Continuing to add test data for the news feature.",
|
content: "This is news item number six. Continuing to add test data for the news feature.",
|
||||||
publishedAt: new Date(),
|
publishedAt: new Date(),
|
||||||
source: {
|
source: {
|
||||||
name: "Test Destination"
|
name: "Test Destination",
|
||||||
|
type: "RSS",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -73,7 +80,8 @@ export function getTestNews (): NewsItem[] {
|
|||||||
content: "Seventh item in the news feed. Sample text to ensure the array has sufficient data.",
|
content: "Seventh item in the news feed. Sample text to ensure the array has sufficient data.",
|
||||||
publishedAt: new Date(),
|
publishedAt: new Date(),
|
||||||
source: {
|
source: {
|
||||||
name: "Test Destination"
|
name: "Test Destination",
|
||||||
|
type: "RSS",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -82,7 +90,8 @@ export function getTestNews (): NewsItem[] {
|
|||||||
content: "News item eight provides more content. This helps in testing the display of multiple items.",
|
content: "News item eight provides more content. This helps in testing the display of multiple items.",
|
||||||
publishedAt: new Date(),
|
publishedAt: new Date(),
|
||||||
source: {
|
source: {
|
||||||
name: "Test Destination"
|
name: "Test Destination",
|
||||||
|
type: "RSS",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -91,7 +100,8 @@ export function getTestNews (): NewsItem[] {
|
|||||||
content: "The ninth news item. Almost reaching the total of 13 items including the original.",
|
content: "The ninth news item. Almost reaching the total of 13 items including the original.",
|
||||||
publishedAt: new Date(),
|
publishedAt: new Date(),
|
||||||
source: {
|
source: {
|
||||||
name: "Test Destination"
|
name: "Test Destination",
|
||||||
|
type: "RSS",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -100,7 +110,8 @@ export function getTestNews (): NewsItem[] {
|
|||||||
content: "Tenth item in the array. This completes the set of additional news items requested.",
|
content: "Tenth item in the array. This completes the set of additional news items requested.",
|
||||||
publishedAt: new Date(),
|
publishedAt: new Date(),
|
||||||
source: {
|
source: {
|
||||||
name: "Test Destination"
|
name: "Test Destination",
|
||||||
|
type: "RSS",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -109,7 +120,8 @@ export function getTestNews (): NewsItem[] {
|
|||||||
content: "Eleventh news item. Continuing to add variety to the test data.",
|
content: "Eleventh news item. Continuing to add variety to the test data.",
|
||||||
publishedAt: new Date(),
|
publishedAt: new Date(),
|
||||||
source: {
|
source: {
|
||||||
name: "Test Destination"
|
name: "Test Destination",
|
||||||
|
type: "RSS",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -118,7 +130,8 @@ export function getTestNews (): NewsItem[] {
|
|||||||
content: "The twelfth and final news item. This brings the total to 13 items in the array.",
|
content: "The twelfth and final news item. This brings the total to 13 items in the array.",
|
||||||
publishedAt: new Date(),
|
publishedAt: new Date(),
|
||||||
source: {
|
source: {
|
||||||
name: "Test Destination"
|
name: "Test Destination",
|
||||||
|
type: "RSS",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
67
src/utils/news/service.ts
Normal file
67
src/utils/news/service.ts
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
import { NewsSource, NewsItem } from "../../api/models/news";
|
||||||
|
|
||||||
|
class NewsSourceTarget {
|
||||||
|
protected source : NewsSource;
|
||||||
|
protected parent : NewsParserService;
|
||||||
|
constructor(source : NewsSource, parent : NewsParserService) {
|
||||||
|
this.source = source;
|
||||||
|
this.parent = parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async readerRSS () : Promise<NewsItem[]> {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
async readAll() : Promise<NewsItem[]> {
|
||||||
|
switch (this.source.type) {
|
||||||
|
case "RSS":
|
||||||
|
return this.readerRSS();
|
||||||
|
default:
|
||||||
|
const impossible: never = this.source.type;
|
||||||
|
return impossible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class NewsParserService {
|
||||||
|
protected sources : Set<NewsSourceTarget> = new Set<NewsSourceTarget>;
|
||||||
|
protected sourceMap : WeakMap<NewsSource, NewsSourceTarget> = new WeakMap<NewsSource, NewsSourceTarget>;
|
||||||
|
|
||||||
|
protected newsItems : Set<NewsItem> = new Set<NewsItem>;
|
||||||
|
|
||||||
|
async setupSources(sources : NewsSource[]) {
|
||||||
|
this.sources.clear();
|
||||||
|
sources.forEach(source => this.addSource(source));
|
||||||
|
}
|
||||||
|
|
||||||
|
async addSource(source : NewsSource) {
|
||||||
|
const sourceTarget = new NewsSourceTarget(source, this);
|
||||||
|
this.sources.add(sourceTarget);
|
||||||
|
this.sourceMap.set(source, sourceTarget);
|
||||||
|
|
||||||
|
const news = await sourceTarget.readAll();
|
||||||
|
news.forEach(newsItem => new Promise<void>((resolve) => {
|
||||||
|
this.newsItems.add(newsItem);
|
||||||
|
resolve();
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
async removeSource(source : NewsSource) {
|
||||||
|
const sourceTarget = this.sourceMap.get(source);
|
||||||
|
if (sourceTarget) {
|
||||||
|
this.sources.delete(sourceTarget);
|
||||||
|
this.sourceMap.delete(source);
|
||||||
|
|
||||||
|
const forDeleting: Set<NewsItem> = new Set<NewsItem>;
|
||||||
|
for (let newsItem of this.newsItems) {
|
||||||
|
if (newsItem.source === source)
|
||||||
|
forDeleting.add(newsItem);
|
||||||
|
}
|
||||||
|
for (let deleteItem of forDeleting) {
|
||||||
|
this.newsItems.delete(deleteItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const newsParserService = new NewsParserService;
|
||||||
44
src/utils/requests.ts
Normal file
44
src/utils/requests.ts
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import http from "http";
|
||||||
|
import https from "https";
|
||||||
|
import { Readable } from "stream";
|
||||||
|
|
||||||
|
type StringUrl = `http${"s" | ""}://${string}`;
|
||||||
|
type Results = string | Buffer | Readable;
|
||||||
|
type ResultType = "string" | "buffer" | "stream";
|
||||||
|
|
||||||
|
export function get(url: StringUrl, type: "string", queries : Record<string, string>): Promise<string>;
|
||||||
|
export function get(url: StringUrl, type: "buffer", queries : Record<string, string>): Promise<Buffer>;
|
||||||
|
export function get(url: StringUrl, type: "stream", queries : Record<string, string>): Promise<Readable>;
|
||||||
|
|
||||||
|
export async function get(
|
||||||
|
url : StringUrl,
|
||||||
|
type : ResultType,
|
||||||
|
queries : Record<string, string> = {}
|
||||||
|
): Promise<Results> {
|
||||||
|
const protocol = url.startsWith("https") ? https : http;
|
||||||
|
|
||||||
|
// Build query string from queries object
|
||||||
|
const queryString = Object.entries(queries)
|
||||||
|
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
|
||||||
|
.join('&');
|
||||||
|
|
||||||
|
const fullUrl = queryString ? `${url}?${queryString}` : url;
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
protocol.get(fullUrl, (res) => {
|
||||||
|
if (type === "stream") {
|
||||||
|
resolve(res);
|
||||||
|
} else if (type === "string") {
|
||||||
|
let data = "";
|
||||||
|
res.on("data", chunk => data += chunk);
|
||||||
|
res.on("end", () => resolve(data));
|
||||||
|
res.on("error", reject);
|
||||||
|
} else if (type === "buffer") {
|
||||||
|
const chunks: Buffer[] = [];
|
||||||
|
res.on("data", chunk => chunks.push(chunk));
|
||||||
|
res.on("end", () => resolve(Buffer.concat(chunks)));
|
||||||
|
res.on("error", reject);
|
||||||
|
}
|
||||||
|
}).on("error", reject);
|
||||||
|
});
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user