forked from sch/Slixfeed
Don't use string formatting and handle timeout and minor changes
Thank you habnabit_
This commit is contained in:
parent
10735697ce
commit
fe00073380
1 changed files with 79 additions and 45 deletions
64
slixfeed.py
64
slixfeed.py
|
@ -1,6 +1,13 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# TODO
|
||||||
|
#
|
||||||
|
# 0) sql prepared statements
|
||||||
|
# 1) Autodetect feed:
|
||||||
|
# if page is not feed (or HTML) and contains <link rel="alternate">
|
||||||
|
# 2) OPML import/export
|
||||||
|
|
||||||
# vars and their meanings:
|
# vars and their meanings:
|
||||||
# cur = Cursor (SQL)
|
# cur = Cursor (SQL)
|
||||||
# jid = Jabber ID (XMPP)
|
# jid = Jabber ID (XMPP)
|
||||||
|
@ -181,7 +188,7 @@ def print_help():
|
||||||
" disable \n"
|
" disable \n"
|
||||||
" Stop sending updates. \n"
|
" Stop sending updates. \n"
|
||||||
" feed list \n"
|
" feed list \n"
|
||||||
" List subscriptions list. \n"
|
" List subscriptions. \n"
|
||||||
"\n"
|
"\n"
|
||||||
"EDIT OPTIONS: \n"
|
"EDIT OPTIONS: \n"
|
||||||
" feed add URL \n"
|
" feed add URL \n"
|
||||||
|
@ -308,6 +315,8 @@ def create_connection(db_file):
|
||||||
return conn
|
return conn
|
||||||
|
|
||||||
|
|
||||||
|
# NOTE I don't think there should be "return"
|
||||||
|
# because then we might stop scanning next URLs
|
||||||
async def download_updates(db_file):
|
async def download_updates(db_file):
|
||||||
with create_connection(db_file) as conn:
|
with create_connection(db_file) as conn:
|
||||||
urls = await get_subscriptions(conn)
|
urls = await get_subscriptions(conn)
|
||||||
|
@ -316,6 +325,13 @@ async def download_updates(db_file):
|
||||||
source = url[0]
|
source = url[0]
|
||||||
res = await download_feed(source)
|
res = await download_feed(source)
|
||||||
|
|
||||||
|
# TypeError: 'NoneType' object is not subscriptable
|
||||||
|
if res is None:
|
||||||
|
# Skip to next feed
|
||||||
|
# urls.next()
|
||||||
|
# next(urls)
|
||||||
|
continue
|
||||||
|
|
||||||
sql = "UPDATE feeds SET status = :status, scanned = :scanned WHERE address = :url"
|
sql = "UPDATE feeds SET status = :status, scanned = :scanned WHERE address = :url"
|
||||||
async with DBLOCK:
|
async with DBLOCK:
|
||||||
with conn:
|
with conn:
|
||||||
|
@ -341,7 +357,7 @@ async def download_updates(db_file):
|
||||||
cur.execute(sql, {"validity": valid, "url": source})
|
cur.execute(sql, {"validity": valid, "url": source})
|
||||||
except (IncompleteReadError, IncompleteRead, error.URLError) as e:
|
except (IncompleteReadError, IncompleteRead, error.URLError) as e:
|
||||||
print(e)
|
print(e)
|
||||||
return
|
# return
|
||||||
# TODO Place these couple of lines back down
|
# TODO Place these couple of lines back down
|
||||||
# NOTE Need to correct the SQL statement to do so
|
# NOTE Need to correct the SQL statement to do so
|
||||||
# NOT SURE WHETHER I MEANT THE LINES ABOVE OR BELOW
|
# NOT SURE WHETHER I MEANT THE LINES ABOVE OR BELOW
|
||||||
|
@ -377,20 +393,33 @@ async def download_updates(db_file):
|
||||||
#print('~~~~~~summary not in entry')
|
#print('~~~~~~summary not in entry')
|
||||||
entry = (title, summary, link, source, 0);
|
entry = (title, summary, link, source, 0);
|
||||||
async with DBLOCK:
|
async with DBLOCK:
|
||||||
|
# print("add entry:", entry)
|
||||||
with conn:
|
with conn:
|
||||||
await add_entry(conn, entry)
|
await add_entry(conn, entry)
|
||||||
await set_date(conn, source)
|
await set_date(conn, source)
|
||||||
|
|
||||||
|
#del length
|
||||||
|
#entries = 0
|
||||||
|
|
||||||
|
|
||||||
async def download_feed(url):
|
async def download_feed(url):
|
||||||
|
timeout = aiohttp.ClientTimeout(total=10)
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
async with session.get(url) as response:
|
# async with aiohttp.ClientSession(trust_env=True) as session:
|
||||||
|
try:
|
||||||
|
async with session.get(url, timeout=timeout) as response:
|
||||||
status = response.status
|
status = response.status
|
||||||
if response.status == 200:
|
if response.status == 200:
|
||||||
doc = await response.text()
|
doc = await response.text()
|
||||||
return [doc, status]
|
return [doc, status]
|
||||||
else:
|
else:
|
||||||
return [False, status]
|
return [False, status]
|
||||||
|
except aiohttp.ClientError as e:
|
||||||
|
print('Error', str(e))
|
||||||
|
return [False, "error"]
|
||||||
|
except asyncio.TimeoutError as e:
|
||||||
|
print('Timeout', str(e))
|
||||||
|
return [False, "timeout"]
|
||||||
|
|
||||||
|
|
||||||
async def check_feed(conn, url):
|
async def check_feed(conn, url):
|
||||||
|
@ -425,7 +454,7 @@ async def add_feed(db_file, url):
|
||||||
return "News source is already listed in the subscription list"
|
return "News source is already listed in the subscription list"
|
||||||
|
|
||||||
async with DBLOCK:
|
async with DBLOCK:
|
||||||
with create_connection(db_file) as conn:
|
with conn:
|
||||||
cur = conn.cursor()
|
cur = conn.cursor()
|
||||||
if res[0]:
|
if res[0]:
|
||||||
feed = feedparser.parse(res[0])
|
feed = feedparser.parse(res[0])
|
||||||
|
@ -450,7 +479,7 @@ async def add_feed(db_file, url):
|
||||||
return "Failed to get URL. HTTP Error {}".format(res[1])
|
return "Failed to get URL. HTTP Error {}".format(res[1])
|
||||||
|
|
||||||
source = title if title else '<' + url + '>'
|
source = title if title else '<' + url + '>'
|
||||||
msg = 'News source "{}" has been added to subscriptions list'.format(source)
|
msg = 'News source "{}" has been added to subscription list'.format(source)
|
||||||
return msg
|
return msg
|
||||||
|
|
||||||
|
|
||||||
|
@ -471,7 +500,7 @@ async def remove_feed(db_file, ix):
|
||||||
cur.execute(sql, (url,))
|
cur.execute(sql, (url,))
|
||||||
sql = "DELETE FROM feeds WHERE id = ?"
|
sql = "DELETE FROM feeds WHERE id = ?"
|
||||||
cur.execute(sql, (ix,))
|
cur.execute(sql, (ix,))
|
||||||
return """News source <{}> has been removed from subscriptions list
|
return """News source <{}> has been removed from subscription list
|
||||||
""".format(url)
|
""".format(url)
|
||||||
|
|
||||||
|
|
||||||
|
@ -482,7 +511,6 @@ async def get_unread(db_file):
|
||||||
:param id: id of the entry
|
:param id: id of the entry
|
||||||
:return: string
|
:return: string
|
||||||
"""
|
"""
|
||||||
async with DBLOCK:
|
|
||||||
with create_connection(db_file) as conn:
|
with create_connection(db_file) as conn:
|
||||||
entry = []
|
entry = []
|
||||||
cur = conn.cursor()
|
cur = conn.cursor()
|
||||||
|
@ -504,17 +532,20 @@ async def get_unread(db_file):
|
||||||
link = cur.fetchone()[0]
|
link = cur.fetchone()[0]
|
||||||
entry.append(link)
|
entry.append(link)
|
||||||
entry = "{}\n\n{}\n\nLink to article:\n{}".format(entry[0], entry[1], entry[2])
|
entry = "{}\n\n{}\n\nLink to article:\n{}".format(entry[0], entry[1], entry[2])
|
||||||
await mark_as_read(cur, ix)
|
print(entry)
|
||||||
|
await mark_as_read(conn, ix)
|
||||||
return entry
|
return entry
|
||||||
|
|
||||||
|
|
||||||
async def mark_as_read(cur, ix):
|
async def mark_as_read(conn, ix):
|
||||||
"""
|
"""
|
||||||
Set read status of entry
|
Set read status of entry
|
||||||
:param cur:
|
:param cur:
|
||||||
:param ix: index of the entry
|
:param ix: index of the entry
|
||||||
"""
|
"""
|
||||||
|
async with DBLOCK:
|
||||||
sql = "UPDATE entries SET summary = '', read = 1 WHERE id = ?"
|
sql = "UPDATE entries SET summary = '', read = 1 WHERE id = ?"
|
||||||
|
cur = conn.cursor()
|
||||||
cur.execute(sql, (ix,))
|
cur.execute(sql, (ix,))
|
||||||
|
|
||||||
|
|
||||||
|
@ -582,8 +613,8 @@ async def set_date(conn, url):
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
today = date.today()
|
today = date.today()
|
||||||
cur = conn.cursor()
|
|
||||||
sql = "UPDATE feeds SET updated = :today WHERE address = :url"
|
sql = "UPDATE feeds SET updated = :today WHERE address = :url"
|
||||||
|
cur = conn.cursor()
|
||||||
cur.execute(sql, {"today": today, "url": url})
|
cur.execute(sql, {"today": today, "url": url})
|
||||||
|
|
||||||
|
|
||||||
|
@ -642,8 +673,9 @@ async def last_entries(db_file, num):
|
||||||
num = 1
|
num = 1
|
||||||
with create_connection(db_file) as conn:
|
with create_connection(db_file) as conn:
|
||||||
cur = conn.cursor()
|
cur = conn.cursor()
|
||||||
sql = "SELECT title, link FROM entries ORDER BY ROWID DESC LIMIT {}".format(num)
|
sql = "SELECT title, link FROM entries ORDER BY ROWID DESC LIMIT :num"
|
||||||
results = cur.execute(sql)
|
results = cur.execute(sql, (num,))
|
||||||
|
|
||||||
|
|
||||||
titles_list = "Recent {} titles: \n".format(num)
|
titles_list = "Recent {} titles: \n".format(num)
|
||||||
for result in results:
|
for result in results:
|
||||||
|
@ -663,8 +695,8 @@ async def search_entries(db_file, query):
|
||||||
|
|
||||||
with create_connection(db_file) as conn:
|
with create_connection(db_file) as conn:
|
||||||
cur = conn.cursor()
|
cur = conn.cursor()
|
||||||
sql = "SELECT title, link FROM entries WHERE title LIKE '%{}%' LIMIT 50".format(query)
|
sql = "SELECT title, link FROM entries WHERE title LIKE ? LIMIT 50"
|
||||||
results = cur.execute(sql)
|
results = cur.execute(sql, [f'%{query}%'])
|
||||||
|
|
||||||
results_list = "Search results for '{}': \n".format(query)
|
results_list = "Search results for '{}': \n".format(query)
|
||||||
counter = 0
|
counter = 0
|
||||||
|
@ -679,6 +711,8 @@ async def search_entries(db_file, query):
|
||||||
|
|
||||||
|
|
||||||
async def check_entry(conn, title, link):
|
async def check_entry(conn, title, link):
|
||||||
|
#print("check_entry")
|
||||||
|
#time.sleep(1)
|
||||||
"""
|
"""
|
||||||
Check whether an entry exists
|
Check whether an entry exists
|
||||||
Query entries by title and link
|
Query entries by title and link
|
||||||
|
@ -687,8 +721,8 @@ async def check_entry(conn, title, link):
|
||||||
:param title:
|
:param title:
|
||||||
:return: row
|
:return: row
|
||||||
"""
|
"""
|
||||||
cur = conn.cursor()
|
|
||||||
sql = "SELECT id FROM entries WHERE title = :title and link = :link"
|
sql = "SELECT id FROM entries WHERE title = :title and link = :link"
|
||||||
|
cur = conn.cursor()
|
||||||
cur.execute(sql, {"title": title, "link": link})
|
cur.execute(sql, {"title": title, "link": link})
|
||||||
return cur.fetchone()
|
return cur.fetchone()
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue