Add option to ignore old news items
This commit is contained in:
parent
c66e09461d
commit
6e7c57d745
4 changed files with 167 additions and 39 deletions
|
@ -47,6 +47,8 @@ async def get_value_default(key):
|
|||
result = randrange(100000, 999999)
|
||||
case "token":
|
||||
result = "none"
|
||||
case "old":
|
||||
result = 0
|
||||
return result
|
||||
|
||||
|
||||
|
|
|
@ -132,7 +132,12 @@ async def download_updates(db_file, url=None):
|
|||
date = entry.updated
|
||||
date = await datetimehandler.rfc2822_to_iso8601(date)
|
||||
else:
|
||||
date = None
|
||||
# TODO Just set date = "*** No date ***"
|
||||
# date = await datetime.now().isoformat()
|
||||
date = await datetimehandler.now()
|
||||
# NOTE Would seconds result in better database performance
|
||||
# date = datetime.datetime(date)
|
||||
# date = (date-datetime.datetime(1970,1,1)).total_seconds()
|
||||
exist = await sqlitehandler.check_entry_exist(
|
||||
db_file,
|
||||
source,
|
||||
|
@ -143,22 +148,19 @@ async def download_updates(db_file, url=None):
|
|||
)
|
||||
if not exist:
|
||||
# new_entry = new_entry + 1
|
||||
if not date:
|
||||
# TODO Just set date = "*** No date ***"
|
||||
# date = await datetime.now().isoformat()
|
||||
date = await datetimehandler.now()
|
||||
# NOTE Would seconds result in better database performance
|
||||
# date = datetime.datetime(date)
|
||||
# date = (date-datetime.datetime(1970,1,1)).total_seconds()
|
||||
# TODO Enhance summary
|
||||
if entry.has_key("summary"):
|
||||
summary = entry.summary
|
||||
# Remove HTML tags
|
||||
summary = BeautifulSoup(summary, "lxml").text
|
||||
# TODO Limit text length
|
||||
summary = summary.replace("\n\n", "\n")[:300] + " ⃨"
|
||||
summary = summary.replace("\n\n\n", "\n\n")
|
||||
summary = summary[:300] + " ⃨"
|
||||
summary = summary.strip().split('\n')
|
||||
summary = ["> " + line for line in summary]
|
||||
summary = "\n".join(summary)
|
||||
else:
|
||||
summary = "*** No summary ***"
|
||||
summary = "> *** No summary ***"
|
||||
read_status = 0
|
||||
pathname = urlsplit(link).path
|
||||
string = (
|
||||
|
|
|
@ -478,23 +478,26 @@ async def get_entry_unread(db_file, num=None):
|
|||
str(summary),
|
||||
str(link)
|
||||
)
|
||||
# TODO While `async with DBLOCK` does work well from
|
||||
# outside of functions, it would be better practice
|
||||
# to place it within the functions.
|
||||
async with DBLOCK:
|
||||
# NOTE: We can use DBLOCK once for both
|
||||
# functions, because, due to exclusive
|
||||
# ID, only one can ever occur.
|
||||
await mark_as_read(cur, ix)
|
||||
await mark_entry_as_read(cur, ix)
|
||||
await delete_entry(cur, ix)
|
||||
return news_list
|
||||
|
||||
|
||||
async def mark_as_read(cur, ix):
|
||||
async def mark_entry_as_read(cur, ix):
|
||||
"""
|
||||
Set read status of entry.
|
||||
Set read status of entry as read.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
db_file : str
|
||||
Path to database file.
|
||||
cur : object
|
||||
Cursor object.
|
||||
ix : str
|
||||
Index of entry.
|
||||
"""
|
||||
|
@ -506,6 +509,51 @@ async def mark_as_read(cur, ix):
|
|||
cur.execute(sql, (ix,))
|
||||
|
||||
|
||||
async def mark_source_as_read(db_file, source):
|
||||
"""
|
||||
Set read status of entries of given source as read.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
db_file : str
|
||||
Path to database file.
|
||||
source : str
|
||||
URL.
|
||||
"""
|
||||
async with DBLOCK:
|
||||
with create_connection(db_file) as conn:
|
||||
cur = conn.cursor()
|
||||
sql = (
|
||||
"UPDATE entries "
|
||||
"SET summary = '', read = 1 "
|
||||
"WHERE source = ?"
|
||||
)
|
||||
cur.execute(sql, (source,))
|
||||
|
||||
|
||||
async def mark_all_as_read(db_file):
|
||||
"""
|
||||
Set read status of all entries as read.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
db_file : str
|
||||
Path to database file.
|
||||
"""
|
||||
async with DBLOCK:
|
||||
with create_connection(db_file) as conn:
|
||||
cur = conn.cursor()
|
||||
sql = (
|
||||
"UPDATE entries "
|
||||
"SET summary = '', read = 1 "
|
||||
)
|
||||
cur.execute(sql)
|
||||
sql = (
|
||||
"DELETE FROM archive"
|
||||
)
|
||||
cur.execute(sql)
|
||||
|
||||
|
||||
async def delete_entry(cur, ix):
|
||||
"""
|
||||
Delete entry from table archive.
|
||||
|
@ -715,6 +763,9 @@ async def add_entry_and_set_date(db_file, source, entry):
|
|||
entry : list
|
||||
Entry properties.
|
||||
"""
|
||||
# TODO While `async with DBLOCK` does work well from
|
||||
# outside of functions, it would be better practice
|
||||
# to place it within the functions.
|
||||
async with DBLOCK:
|
||||
with create_connection(db_file) as conn:
|
||||
cur = conn.cursor()
|
||||
|
|
|
@ -274,6 +274,13 @@ class Slixfeed(slixmpp.ClientXMPP):
|
|||
|
||||
|
||||
async def remove_and_leave_muc(self, muc_jid):
|
||||
self.send_message(
|
||||
mto=muc_jid,
|
||||
mbody=(
|
||||
"If you need me again, contact me directly at {}\n"
|
||||
"Goodbye!"
|
||||
).format(self.boundjid.bare)
|
||||
)
|
||||
result = await self.plugin['xep_0048'].get_bookmarks()
|
||||
bookmarks = result["private"]["bookmarks"]
|
||||
conferences = bookmarks["conferences"]
|
||||
|
@ -661,13 +668,28 @@ class Slixfeed(slixmpp.ClientXMPP):
|
|||
datahandler.add_feed_no_check,
|
||||
[url, title]
|
||||
)
|
||||
await taskhandler.refresh_task(
|
||||
self,
|
||||
old = await filehandler.initdb(
|
||||
jid,
|
||||
taskhandler.send_status,
|
||||
"status",
|
||||
20
|
||||
sqlitehandler.get_settings_value,
|
||||
"old"
|
||||
)
|
||||
if old:
|
||||
await taskhandler.clean_tasks_xmpp(
|
||||
jid,
|
||||
["status"]
|
||||
)
|
||||
# await taskhandler.send_status(jid)
|
||||
await taskhandler.start_tasks_xmpp(
|
||||
self,
|
||||
jid,
|
||||
["status"]
|
||||
)
|
||||
else:
|
||||
await filehandler.initdb(
|
||||
jid,
|
||||
sqlitehandler.mark_source_as_read,
|
||||
url
|
||||
)
|
||||
else:
|
||||
action = "Missing URL."
|
||||
case _ if message_lowercase.startswith("allow +"):
|
||||
|
@ -789,16 +811,28 @@ class Slixfeed(slixmpp.ClientXMPP):
|
|||
# 20
|
||||
# )
|
||||
# NOTE This would show the number of new unread entries
|
||||
await taskhandler.clean_tasks_xmpp(
|
||||
old = await filehandler.initdb(
|
||||
jid,
|
||||
["status"]
|
||||
)
|
||||
# await taskhandler.send_status(jid)
|
||||
await taskhandler.start_tasks_xmpp(
|
||||
self,
|
||||
jid,
|
||||
["status"]
|
||||
sqlitehandler.get_settings_value,
|
||||
"old"
|
||||
)
|
||||
if old:
|
||||
await taskhandler.clean_tasks_xmpp(
|
||||
jid,
|
||||
["status"]
|
||||
)
|
||||
# await taskhandler.send_status(jid)
|
||||
await taskhandler.start_tasks_xmpp(
|
||||
self,
|
||||
jid,
|
||||
["status"]
|
||||
)
|
||||
else:
|
||||
await filehandler.initdb(
|
||||
jid,
|
||||
sqlitehandler.mark_source_as_read,
|
||||
url
|
||||
)
|
||||
case _ if message_lowercase.startswith("feeds"):
|
||||
query = message[6:]
|
||||
if query:
|
||||
|
@ -839,6 +873,8 @@ class Slixfeed(slixmpp.ClientXMPP):
|
|||
sqlitehandler.set_settings_value,
|
||||
[key, val]
|
||||
)
|
||||
# NOTE Perhaps this should be replaced
|
||||
# by functions clean and start
|
||||
await taskhandler.refresh_task(
|
||||
self,
|
||||
jid,
|
||||
|
@ -878,6 +914,15 @@ class Slixfeed(slixmpp.ClientXMPP):
|
|||
).format(val)
|
||||
else:
|
||||
action = "Missing value."
|
||||
case "new":
|
||||
await filehandler.initdb(
|
||||
jid,
|
||||
sqlitehandler.set_settings_value,
|
||||
["old", 0]
|
||||
)
|
||||
action = (
|
||||
"Only new items of added feeds will be sent."
|
||||
)
|
||||
case _ if message_lowercase.startswith("next"):
|
||||
num = message[5:]
|
||||
await taskhandler.clean_tasks_xmpp(
|
||||
|
@ -904,6 +949,15 @@ class Slixfeed(slixmpp.ClientXMPP):
|
|||
# 20
|
||||
# )
|
||||
# await taskhandler.refresh_task(jid, key, val)
|
||||
case "old":
|
||||
await filehandler.initdb(
|
||||
jid,
|
||||
sqlitehandler.set_settings_value,
|
||||
["old", 1]
|
||||
)
|
||||
action = (
|
||||
"All items of added feeds will be sent."
|
||||
)
|
||||
case _ if message_lowercase.startswith("quantum"):
|
||||
key = message[:7]
|
||||
val = message[8:]
|
||||
|
@ -1089,20 +1143,31 @@ def print_info():
|
|||
"""
|
||||
msg = (
|
||||
"```\n"
|
||||
"NAME\n"
|
||||
"Slixfeed - News syndication bot for Jabber/XMPP\n"
|
||||
"ABOUT\n"
|
||||
" Slixfeed aims to be an easy to use and fully-featured news\n"
|
||||
" aggregator bot for XMPP. It provides a convenient access to Blogs,\n"
|
||||
" Fediverse and News websites along with filtering functionality."
|
||||
"\n"
|
||||
"DESCRIPTION\n"
|
||||
" Slixfeed is a news aggregator bot for online news feeds.\n"
|
||||
" This program is primarily designed for XMPP.\n"
|
||||
" For more information, visit https://xmpp.org/software/\n"
|
||||
" Slixfeed is primarily designed for XMPP (aka Jabber).\n"
|
||||
" Visit https://xmpp.org/software/ for more information.\n"
|
||||
"\n"
|
||||
# "PROTOCOLS\n"
|
||||
# " Supported prootcols are IRC, Matrix and XMPP.\n"
|
||||
" XMPP is the Extensible Messaging and Presence Protocol, a set\n"
|
||||
" of open technologies for instant messaging, presence, multi-party\n"
|
||||
" chat, voice and video calls, collaboration, lightweight\n"
|
||||
" middleware, content syndication, and generalized routing of XML\n"
|
||||
" data."
|
||||
" Visit https://xmpp.org/about/ for more information on the XMPP\n"
|
||||
" protocol."
|
||||
" "
|
||||
# "PLATFORMS\n"
|
||||
# " Supported prootcols are IRC, Matrix, Tox and XMPP.\n"
|
||||
# " For the best experience, we recommend you to use XMPP.\n"
|
||||
# "\n"
|
||||
"FILETYPES\n"
|
||||
" Supported filetypes are Atom, RDF and RSS.\n"
|
||||
" Supported filetypes: Atom, RDF, RSS and XML.\n"
|
||||
"\n"
|
||||
"PROTOCOLS\n"
|
||||
" Supported protocols: Dat, FTP, Gemini, Gopher, HTTP and IPFS.\n"
|
||||
"\n"
|
||||
"AUTHORS\n"
|
||||
" Laura Harbinger, Schimon Zackary.\n"
|
||||
|
@ -1118,11 +1183,15 @@ def print_info():
|
|||
" Florent Le Coz (poezio, France),"
|
||||
"\n"
|
||||
" George Vlahavas (SalixOS, Greece),"
|
||||
" Maxime Buquet (slixmpp, France),"
|
||||
"\n"
|
||||
" Mathieu Pasquet (slixmpp, France),"
|
||||
" Pierrick Le Brun (SalixOS, France),"
|
||||
"\n"
|
||||
" Remko Tronçon (Swift, Germany),"
|
||||
" Thorsten Mühlfelder (SalixOS, Germany),"
|
||||
" Yann Leboulanger (Gajim, France).\n"
|
||||
"\n"
|
||||
" Yann Leboulanger (Gajim, France).\n"
|
||||
"COPYRIGHT\n"
|
||||
" Slixfeed is free software; you can redistribute it and/or\n"
|
||||
" modify it under the terms of the GNU General Public License\n"
|
||||
|
@ -1135,7 +1204,7 @@ def print_info():
|
|||
"\n"
|
||||
"NOTE\n"
|
||||
" You can run Slixfeed on your own computer, server, and\n"
|
||||
" even on a Linux phone (i.e. Droidian, Mobian NixOS,\n"
|
||||
" even on a Linux phone (i.e. Droidian, Kupfer, Mobian, NixOS,\n"
|
||||
" postmarketOS). You can also use Termux.\n"
|
||||
"\n"
|
||||
" All you need is one of the above and an XMPP account to\n"
|
||||
|
@ -1183,6 +1252,10 @@ def print_help():
|
|||
" Display most recent 20 titles of given URL.\n"
|
||||
" read URL N\n"
|
||||
" Display specified entry number from given URL.\n"
|
||||
" new\n"
|
||||
" Send only new items of added feeds.\n"
|
||||
" old\n"
|
||||
" Send all items of added feeds.\n"
|
||||
"\n"
|
||||
"MESSAGE OPTIONS\n"
|
||||
" start\n"
|
||||
|
|
Loading…
Reference in a new issue