From 061c450f41c7fab33de83ceb0a0890edaa3a09e2 Mon Sep 17 00:00:00 2001 From: mdivecky Date: Sat, 26 Aug 2023 12:32:18 +0200 Subject: [PATCH] Implemented filtering by feed on backend. Non-ideal solution prone to possible sql injection... --- view/app.py | 72 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 53 insertions(+), 19 deletions(-) diff --git a/view/app.py b/view/app.py index 2c0f117..4f493db 100644 --- a/view/app.py +++ b/view/app.py @@ -8,7 +8,7 @@ import confuse import re -DATABASE = "../data/diffs.db" +DATABASE = "file:../data/diffs.db?mode=ro" CONFIG_FILE = "../data/config.yaml" config = confuse.Configuration("headline", __name__) @@ -24,7 +24,7 @@ assets.url_expire = False def get_db(): db = getattr(g, "_database", None) if db is None: - db = g._database = sqlite3.connect(DATABASE) + db = g._database = sqlite3.connect(DATABASE, uri=True) db.row_factory = sqlite3.Row return db @@ -68,33 +68,67 @@ def index(): query = websearch_to_fts_query(search) if search else None selected_feeds = request.args.getlist("feeds[]") - db.execute( - f"SELECT count(*) FROM diffs{'_fts(?)' if query else ''}", - (query,) if query else (), - ) + sql_select = "SELECT * FROM diffs " + sql_count = "SELECT count(*) FROM diffs " - diff_count = db.fetchall()[0][0] + if query: + sql_part_query = f"JOIN (SELECT rowid FROM diffs_fts({query})) filter ON filter.rowid = diffs.diff_id " + sql_select = sql_select + sql_part_query + sql_count = sql_count + sql_part_query + + if selected_feeds: + feeds = str(selected_feeds).strip("[]") + sql_part_feeds = f"WHERE feed_name in ({feeds}) " + sql_select = sql_select + sql_part_feeds + sql_count = sql_count + sql_part_feeds # flask-paginate page = request.args.get(get_page_parameter(), type=int, default=1) + db.execute(sql_count) + diff_count = db.fetchall()[0][0] pagination = Pagination( page=page, total=diff_count, record_name="diffs", css_framework="bootstrap5" ) - - # TODO: implement filtering by feeds page_skip = pagination.skip per_page = pagination.per_page - if query: - db.execute( - "SELECT * FROM diffs JOIN (SELECT rowid FROM diffs_fts(?)) filter ON filter.rowid = diffs.diff_id ORDER BY diff_id DESC LIMIT ? OFFSET ?", - (query, per_page, page_skip), - ) - else: - db.execute( - "SELECT * FROM diffs ORDER BY diff_id DESC LIMIT ? OFFSET ?", - (per_page, page_skip), - ) + + # Create and execute final query after getting page info + sql_part_pagination = f"ORDER BY diff_id DESC LIMIT {per_page} OFFSET {page_skip} " + sql_select = sql_select + sql_part_pagination + print(sql_select) + db.execute(sql_select) + + # This would be a cleaner way to do it, but I have no clue how to make it work. Giving multiple feeds to the query is just seemingly impossible in sqlite. + # What about switching to Elasticsearch? :) + + # if selected_feeds and query: + # feeds = str(selected_feeds).strip("[]") + # db.execute( + # "SELECT * FROM diffs JOIN (SELECT rowid FROM diffs_fts(?)) filter ON filter.rowid = diffs.diff_id WHERE feed_name IN (?) ORDER BY diff_id DESC LIMIT ? OFFSET ?", + # (query, feeds, per_page, page_skip), + # ) + + # elif query: + # db.execute( + # "SELECT * FROM diffs JOIN (SELECT rowid FROM diffs_fts(?)) filter ON filter.rowid = diffs.diff_id ORDER BY diff_id DESC LIMIT ? OFFSET ?", + # (query, per_page, page_skip), + # ) + + # elif selected_feeds: + # feeds = str(selected_feeds).strip("[]").replace("'", '"') + # print(feeds) + # db.execute( + # f"SELECT * FROM diffs WHERE feed_name IN ({','.join(['?']*len(selected_feeds))}) ORDER BY diff_id DESC LIMIT ? OFFSET ?", + # (selected_feeds, per_page, page_skip), + # ) + + # else: + # db.execute( + # "SELECT * FROM diffs ORDER BY diff_id DESC LIMIT ? OFFSET ?", + # (per_page, page_skip), + # ) + diffs = db.fetchall() html = render_template(