From 047b9707ee235113a923b67e4b3e4da3b21c0e92 Mon Sep 17 00:00:00 2001 From: parissak <56480346+parissak@users.noreply.github.com> Date: Thu, 13 Jun 2024 22:23:54 +0300 Subject: [PATCH] feat(filtering): add backend and frontend functionality --- client/src/App.tsx | 51 ++++++++++++++++++++++++ client/src/services/database_queries.tsx | 11 +++++ server/app.py | 20 ++++++++++ 3 files changed, 82 insertions(+) create mode 100644 client/src/services/database_queries.tsx diff --git a/client/src/App.tsx b/client/src/App.tsx index e10ffcf..1af2006 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -1,6 +1,7 @@ import React, { useEffect, useState } from 'react'; import { getAllFeedUrls, sendAllFeedUrls } from './services/feed_urls'; import { keepFetching, stopFetching } from './services/fetching-news'; +import { sendSearchQuery } from './services/database_queries'; import axios from 'axios'; import './css/index.css'; import { @@ -13,12 +14,18 @@ import { import { Button } from '@/components/ui/button'; import { toast } from 'sonner'; import { ThemeProvider } from './components/ui/theme-provider'; +import { Textarea } from './components/ui/textarea'; import QuestionsAccordion from './components/questions-accordion'; import Footer from './components/footer'; import RssInput from './components/rss-input'; import Header from './components/header'; +type Article = { + time: string; + url: string; +}; + // eslint-disable-next-line react-refresh/only-export-components export const serverUrl = import.meta.env.PROD ? 'http://localhost:4000' @@ -28,6 +35,8 @@ function App() { const [feedUrls, setFeedUrls] = useState(''); const [isDisabled, setIsDisabled] = useState(false); const [isFetching, setIsFetching] = useState(false); + const [searchData, setSearchData] = useState([]); + const [searchQuery, setSearchQuery] = useState(''); const handleInputChange = (event: { target: { value: React.SetStateAction }; @@ -35,6 +44,12 @@ function App() { setFeedUrls(event.target.value); }; + const handleFilterInputChange = (event: { + target: { value: React.SetStateAction }; + }) => { + setSearchQuery(event.target.value); + }; + const handleSubmit = async () => { toast.dismiss(); const rssFeeds = feedUrls @@ -118,6 +133,11 @@ function App() { }, toastOptions); }; + const handleSearchQuery = async () => { + const data = await sendSearchQuery(searchQuery); + setSearchData(data); + }; + useEffect(() => { const fetchFeedUrls = async () => { const feedUrls = await getAllFeedUrls(); @@ -181,6 +201,37 @@ function App() { + + + + +
+
    + {searchData.map((item, index) => ( +
  • +

    + Time: {item.time} +

    +

    + URL: {item.url} +

    +
  • + ))} +
+
+
diff --git a/client/src/services/database_queries.tsx b/client/src/services/database_queries.tsx new file mode 100644 index 0000000..7c1317f --- /dev/null +++ b/client/src/services/database_queries.tsx @@ -0,0 +1,11 @@ +import axios from 'axios'; +import { serverUrl } from '../App'; + +const sendSearchQuery = async (searchQuery: string) => { + const response = await axios.get(`${serverUrl}/api/articles/search`, { + params: { searchQuery: searchQuery } + }); + return response.data +}; + +export { sendSearchQuery }; diff --git a/server/app.py b/server/app.py index f6538b6..6ac2efa 100644 --- a/server/app.py +++ b/server/app.py @@ -7,6 +7,13 @@ import subprocess from datetime import datetime +from sqlalchemy import create_engine, MetaData, text + +os.makedirs("./rss-fetcher/", exist_ok=True) +engine = create_engine(f'sqlite:///./rss-fetcher/data.db', echo=False) +meta = MetaData() +connection = engine.connect() + app = Flask(__name__, static_folder='static') CORS(app, resources={r"/*": {"origins": "*"}}) @@ -69,6 +76,19 @@ def download_articles(): print("Running process and export resulted in failure") print("Error: ", e.stderr) +@app.route('/api/articles/search', methods=['GET']) +def search_articles(): + try: + search_query = request.args.get('searchQuery', '') + stmt = text("SELECT time, url FROM articles WHERE full_text LIKE :word") + stmt = stmt.bindparams(word=f'%{search_query}%') + result = connection.execute(stmt) + rows = result.fetchall() + data = [{"time": time, "url": url} for time, url in rows] + return jsonify(data), 200 + except Exception as e: + print("Error: ", e) + return jsonify({"status": "error", "message": str(e)}), 500 if __name__ == '__main__': app.run(host='0.0.0.0', port=5000)