Laura
This commit is contained in:
parent
0c32f95814
commit
2e23e93584
1 changed files with 280 additions and 432 deletions
484
slixfeed.py
484
slixfeed.py
|
@ -1,46 +1,31 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
import os
|
||||||
Created on Sun May 15 17:09:05 2022
|
|
||||||
|
|
||||||
@author: Schimon Jehudah, Adv.
|
|
||||||
"""
|
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
from asyncio.exceptions import IncompleteReadError
|
from asyncio.exceptions import IncompleteReadError
|
||||||
from bs4 import BeautifulSoup
|
|
||||||
from datetime import date
|
from datetime import date
|
||||||
from getpass import getpass
|
from getpass import getpass
|
||||||
from http.client import IncompleteRead
|
from http.client import IncompleteRead
|
||||||
from os import path
|
|
||||||
from urllib import error
|
from urllib import error
|
||||||
#from urllib.parse import urlparse
|
|
||||||
#from xdg import BaseDirectory
|
|
||||||
|
|
||||||
import aiohttp
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import feedparser
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
|
||||||
import os.path
|
|
||||||
import slixmpp
|
|
||||||
import sqlite3
|
import sqlite3
|
||||||
from sqlite3 import Error
|
from sqlite3 import Error
|
||||||
import sys
|
import sys
|
||||||
import time
|
|
||||||
#import xdg
|
|
||||||
|
|
||||||
# offline = False
|
import aiohttp
|
||||||
|
from bs4 import BeautifulSoup
|
||||||
|
import feedparser
|
||||||
|
import slixmpp
|
||||||
|
|
||||||
|
DBLOCK = asyncio.Lock()
|
||||||
|
|
||||||
|
|
||||||
class Slixfeed(slixmpp.ClientXMPP):
|
class Slixfeed(slixmpp.ClientXMPP):
|
||||||
"""
|
"""
|
||||||
Slixmpp bot that will send updates of feeds it
|
Slixmpp bot that will send updates of feeds it
|
||||||
receives.
|
receives.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
lock = asyncio.Lock()
|
|
||||||
print("locked?")
|
|
||||||
print(lock.locked())
|
|
||||||
|
|
||||||
def __init__(self, jid, password):
|
def __init__(self, jid, password):
|
||||||
slixmpp.ClientXMPP.__init__(self, jid, password)
|
slixmpp.ClientXMPP.__init__(self, jid, password)
|
||||||
|
|
||||||
|
@ -51,6 +36,7 @@ class Slixfeed(slixmpp.ClientXMPP):
|
||||||
# our roster.
|
# our roster.
|
||||||
self.add_event_handler("session_start", self.start)
|
self.add_event_handler("session_start", self.start)
|
||||||
self.add_event_handler("session_start", self.send_updates)
|
self.add_event_handler("session_start", self.send_updates)
|
||||||
|
self.add_event_handler("session_start", self.check_updates)
|
||||||
|
|
||||||
# The message event is triggered whenever a message
|
# The message event is triggered whenever a message
|
||||||
# stanza is received. Be aware that that includes
|
# stanza is received. Be aware that that includes
|
||||||
|
@ -58,14 +44,6 @@ class Slixfeed(slixmpp.ClientXMPP):
|
||||||
self.add_event_handler("message", self.message)
|
self.add_event_handler("message", self.message)
|
||||||
self.add_event_handler("disconnected", self.reconnect)
|
self.add_event_handler("disconnected", self.reconnect)
|
||||||
|
|
||||||
# async def reconnect(self, event):
|
|
||||||
# await asyncio.sleep(10)
|
|
||||||
# offline = True
|
|
||||||
# print(time.strftime("%H:%M:%S"))
|
|
||||||
# print(offline)
|
|
||||||
# self.connect()
|
|
||||||
# #return True
|
|
||||||
|
|
||||||
async def start(self, event):
|
async def start(self, event):
|
||||||
"""
|
"""
|
||||||
Process the session_start event.
|
Process the session_start event.
|
||||||
|
@ -104,65 +82,59 @@ class Slixfeed(slixmpp.ClientXMPP):
|
||||||
elif message.lower().startswith('feed recent '):
|
elif message.lower().startswith('feed recent '):
|
||||||
print("COMMAND: feed recent")
|
print("COMMAND: feed recent")
|
||||||
print("ACCOUNT: " + str(msg['from']))
|
print("ACCOUNT: " + str(msg['from']))
|
||||||
action = await initdb(msg['from'].bare,
|
action = await initdb(msg['from'].bare, last_entries, message[12:])
|
||||||
False,
|
|
||||||
message[12:],
|
|
||||||
last_entries)
|
|
||||||
elif message.lower().startswith('feed search '):
|
elif message.lower().startswith('feed search '):
|
||||||
print("COMMAND: feed search")
|
print("COMMAND: feed search")
|
||||||
print("ACCOUNT: " + str(msg['from']))
|
print("ACCOUNT: " + str(msg['from']))
|
||||||
action = await initdb(msg['from'].bare,
|
action = await initdb( msg['from'].bare, search_entries, message[12:])
|
||||||
False,
|
|
||||||
message[12:],
|
|
||||||
search_entries)
|
|
||||||
elif message.lower().startswith('feed list'):
|
elif message.lower().startswith('feed list'):
|
||||||
print("COMMAND: feed list")
|
print("COMMAND: feed list")
|
||||||
print("ACCOUNT: " + str(msg['from']))
|
print("ACCOUNT: " + str(msg['from']))
|
||||||
action = await initdb(msg['from'].bare,
|
action = await initdb(msg['from'].bare, list_subscriptions)
|
||||||
False,
|
|
||||||
False,
|
|
||||||
list_subscriptions)
|
|
||||||
elif message.lower().startswith('feed add '):
|
elif message.lower().startswith('feed add '):
|
||||||
print("COMMAND: feed add")
|
print("COMMAND: feed add")
|
||||||
print("ACCOUNT: " + str(msg['from']))
|
print("ACCOUNT: " + str(msg['from']))
|
||||||
action = await initdb(msg['from'].bare,
|
action = await initdb(msg['from'].bare, add_feed, message[9:])
|
||||||
self.lock,
|
|
||||||
message[9:],
|
|
||||||
add_feed)
|
|
||||||
elif message.lower().startswith('feed remove '):
|
elif message.lower().startswith('feed remove '):
|
||||||
print("COMMAND: feed remove")
|
print("COMMAND: feed remove")
|
||||||
print("ACCOUNT: " + str(msg['from']))
|
print("ACCOUNT: " + str(msg['from']))
|
||||||
action = await initdb(msg['from'].bare,
|
action = await initdb(msg['from'].bare, remove_feed, message[12:])
|
||||||
self.lock,
|
|
||||||
message[12:],
|
|
||||||
remove_feed)
|
|
||||||
elif message.lower().startswith('feed status '):
|
elif message.lower().startswith('feed status '):
|
||||||
print("COMMAND: feed status")
|
print("COMMAND: feed status")
|
||||||
print("ACCOUNT: " + str(msg['from']))
|
print("ACCOUNT: " + str(msg['from']))
|
||||||
action = await initdb(msg['from'].bare,
|
action = await initdb(msg['from'].bare, toggle_status, message[12:])
|
||||||
self.lock,
|
|
||||||
message[12:],
|
|
||||||
toggle_status)
|
|
||||||
elif message.lower().startswith('enable'):
|
elif message.lower().startswith('enable'):
|
||||||
print("COMMAND: enable")
|
print("COMMAND: enable")
|
||||||
print("ACCOUNT: " + str(msg['from']))
|
print("ACCOUNT: " + str(msg['from']))
|
||||||
action = toggle_state(msg['from'].bare,
|
action = toggle_state(msg['from'].bare, True)
|
||||||
True)
|
|
||||||
elif message.lower().startswith('disable'):
|
elif message.lower().startswith('disable'):
|
||||||
print("COMMAND: disable")
|
print("COMMAND: disable")
|
||||||
print("ACCOUNT: " + str(msg['from']))
|
print("ACCOUNT: " + str(msg['from']))
|
||||||
action = toggle_state(msg['from'].bare,
|
action = toggle_state(msg['from'].bare, False)
|
||||||
False)
|
|
||||||
else:
|
else:
|
||||||
action = "Unknown command. Press \"help\" for list of commands"
|
action = 'Unknown command. Press "help" for list of commands'
|
||||||
msg.reply(action).send()
|
msg.reply(action).send()
|
||||||
|
|
||||||
async def send_updates(self, event):
|
async def check_updates(self, event):
|
||||||
#while not offline:
|
while True:
|
||||||
|
print("Checking update")
|
||||||
|
db_dir = get_default_dbdir()
|
||||||
|
if not os.path.isdir(db_dir):
|
||||||
|
msg = ("Slixfeed can not work without a database. \n"
|
||||||
|
"To create a database, follow these steps: \n"
|
||||||
|
"Add Slixfeed contact to your roster \n"
|
||||||
|
"Send a feed to the bot by: \n"
|
||||||
|
"feed add https://reclaimthenet.org/feed/")
|
||||||
|
print(msg)
|
||||||
|
else:
|
||||||
|
files = os.listdir(db_dir)
|
||||||
|
for file in files:
|
||||||
|
jid = file[:-3]
|
||||||
|
await initdb(jid, download_updates)
|
||||||
|
await asyncio.sleep(9)
|
||||||
|
|
||||||
|
async def send_updates(self, event):
|
||||||
while True:
|
while True:
|
||||||
#async with self.lock:
|
|
||||||
print(time.strftime("%H:%M:%S"))
|
|
||||||
# print(offline)
|
|
||||||
db_dir = get_default_dbdir()
|
db_dir = get_default_dbdir()
|
||||||
if not os.path.isdir(db_dir):
|
if not os.path.isdir(db_dir):
|
||||||
msg = ("Slixfeed can not work without a database. \n"
|
msg = ("Slixfeed can not work without a database. \n"
|
||||||
|
@ -177,71 +149,19 @@ class Slixfeed(slixmpp.ClientXMPP):
|
||||||
for file in files:
|
for file in files:
|
||||||
if not file.endswith('.db-jour.db'):
|
if not file.endswith('.db-jour.db'):
|
||||||
jid = file[:-3]
|
jid = file[:-3]
|
||||||
# TODO check if jid online
|
new = await initdb(
|
||||||
# https://slixmpp.readthedocs.io/en/latest/api/plugins/xep_0199.html
|
jid,
|
||||||
# d = self.send_ping(self, jid)
|
get_unread
|
||||||
# print('d')
|
)
|
||||||
# print(d)
|
|
||||||
new = await initdb(jid, self.lock, False, get_unread)
|
|
||||||
if new:
|
if new:
|
||||||
msg = self.make_message(mto=jid, mbody=new,
|
msg = self.make_message(
|
||||||
mtype='chat')
|
mto=jid,
|
||||||
|
mbody=new,
|
||||||
|
mtype='chat'
|
||||||
|
)
|
||||||
msg.send()
|
msg.send()
|
||||||
# today = str(date.today())
|
|
||||||
# news.insert = [0, 'News fetched on: ' + today]
|
|
||||||
#news.append('End of News update')
|
|
||||||
#for new in news:
|
|
||||||
#print("sending to: jid")
|
|
||||||
#print("sending to: " + jid)
|
|
||||||
# self.send_message(mto=jid,
|
|
||||||
# mbody=new,
|
|
||||||
# mtype='normal').send()
|
|
||||||
#msg = self.make_message(mto=jid,
|
|
||||||
# mbody=new,
|
|
||||||
# mtype='chat')
|
|
||||||
#print(msg)
|
|
||||||
#msg.send()
|
|
||||||
await asyncio.sleep(60 * 3)
|
await asyncio.sleep(60 * 3)
|
||||||
|
|
||||||
# asyncio.ensure_future(send_updates(self))
|
|
||||||
|
|
||||||
async def check_updates():
|
|
||||||
#async with Slixfeed.lock:
|
|
||||||
while True:
|
|
||||||
db_dir = get_default_dbdir()
|
|
||||||
if not os.path.isdir(db_dir):
|
|
||||||
msg = ("Slixfeed can not work without a database. \n"
|
|
||||||
"To create a database, follow these steps: \n"
|
|
||||||
"Add Slixfeed contact to your roster \n"
|
|
||||||
"Send a feed to the bot by: \n"
|
|
||||||
"feed add https://reclaimthenet.org/feed/")
|
|
||||||
print(msg)
|
|
||||||
else:
|
|
||||||
os.chdir(db_dir)
|
|
||||||
files = os.listdir()
|
|
||||||
for file in files:
|
|
||||||
jid = file[:-3]
|
|
||||||
await initdb(
|
|
||||||
jid,
|
|
||||||
Slixfeed.lock,
|
|
||||||
False,
|
|
||||||
download_updates
|
|
||||||
)
|
|
||||||
await asyncio.sleep(60 * 30)
|
|
||||||
|
|
||||||
asyncio.ensure_future(check_updates())
|
|
||||||
|
|
||||||
# async def tasks():
|
|
||||||
# # Begin scanning feeds
|
|
||||||
# task = asyncio.create_task(check_updates())
|
|
||||||
# await task
|
|
||||||
|
|
||||||
async def tasks(jid, password):
|
|
||||||
# Begin scanning feeds
|
|
||||||
await asyncio.gather(
|
|
||||||
check_updates(),
|
|
||||||
Slixfeed(jid, password).send_updates()
|
|
||||||
)
|
|
||||||
|
|
||||||
def print_help():
|
def print_help():
|
||||||
msg = ("Slixfeed - News syndication bot for Jabber/XMPP \n"
|
msg = ("Slixfeed - News syndication bot for Jabber/XMPP \n"
|
||||||
|
@ -280,6 +200,7 @@ def print_help():
|
||||||
" https://pythonhosted.org/feedparser")
|
" https://pythonhosted.org/feedparser")
|
||||||
return msg
|
return msg
|
||||||
|
|
||||||
|
|
||||||
# Function from buku
|
# Function from buku
|
||||||
# https://github.com/jarun/buku
|
# https://github.com/jarun/buku
|
||||||
# Arun Prakash Jana (jarun)
|
# Arun Prakash Jana (jarun)
|
||||||
|
@ -311,15 +232,24 @@ def get_default_dbdir():
|
||||||
data_home = os.path.join(os.environ.get('HOME'), '.local', 'share')
|
data_home = os.path.join(os.environ.get('HOME'), '.local', 'share')
|
||||||
return os.path.join(data_home, 'slixfeed')
|
return os.path.join(data_home, 'slixfeed')
|
||||||
|
|
||||||
|
|
||||||
# TODO Perhaps this needs to be executed
|
# TODO Perhaps this needs to be executed
|
||||||
# just once per program execution
|
# just once per program execution
|
||||||
async def initdb(jid, lock, message, callback):
|
async def initdb(jid, callback, message=None):
|
||||||
print("initdb(jid, lock, message, callback)")
|
|
||||||
db_dir = get_default_dbdir()
|
db_dir = get_default_dbdir()
|
||||||
if not os.path.isdir(db_dir):
|
if not os.path.isdir(db_dir):
|
||||||
os.mkdir(db_dir)
|
os.mkdir(db_dir)
|
||||||
os.chdir(db_dir)
|
db_file = os.path.join(db_dir, r"{}.db".format(jid))
|
||||||
db_file = r"{}.db".format(jid)
|
create_tables(db_file)
|
||||||
|
|
||||||
|
if message:
|
||||||
|
return await callback(db_file, message)
|
||||||
|
else:
|
||||||
|
return await callback(db_file)
|
||||||
|
|
||||||
|
|
||||||
|
def create_tables(db_file):
|
||||||
|
with create_connection(db_file) as conn:
|
||||||
feeds_table_sql = """
|
feeds_table_sql = """
|
||||||
CREATE TABLE IF NOT EXISTS feeds (
|
CREATE TABLE IF NOT EXISTS feeds (
|
||||||
id integer PRIMARY KEY,
|
id integer PRIMARY KEY,
|
||||||
|
@ -340,30 +270,11 @@ async def initdb(jid, lock, message, callback):
|
||||||
source text,
|
source text,
|
||||||
read integer
|
read integer
|
||||||
); """
|
); """
|
||||||
# create a database connection
|
|
||||||
conn = create_connection(db_file)
|
c = conn.cursor()
|
||||||
# create tables
|
c.execute(feeds_table_sql)
|
||||||
if conn is not None:
|
c.execute(entries_table_sql)
|
||||||
# create projects table
|
|
||||||
create_table(conn, feeds_table_sql)
|
|
||||||
create_table(conn, entries_table_sql)
|
|
||||||
else:
|
|
||||||
print("Error! cannot create the database connection.")
|
|
||||||
if lock:
|
|
||||||
if message:
|
|
||||||
print("if message")
|
|
||||||
print(message)
|
|
||||||
print(lock.locked())
|
|
||||||
return await callback(conn, lock, message)
|
|
||||||
else:
|
|
||||||
print("if message else")
|
|
||||||
print(lock.locked())
|
|
||||||
return await callback(conn, lock)
|
|
||||||
elif message:
|
|
||||||
return await callback(conn, message)
|
|
||||||
else:
|
|
||||||
print("lock else")
|
|
||||||
return await callback(conn)
|
|
||||||
|
|
||||||
def create_connection(db_file):
|
def create_connection(db_file):
|
||||||
"""
|
"""
|
||||||
|
@ -380,38 +291,21 @@ def create_connection(db_file):
|
||||||
print(e)
|
print(e)
|
||||||
return conn
|
return conn
|
||||||
|
|
||||||
def create_table(conn, create_table_sql):
|
|
||||||
"""
|
|
||||||
Create a table from the create_table_sql statement
|
|
||||||
:param conn: Connection object
|
|
||||||
:param create_table_sql: a CREATE TABLE statement
|
|
||||||
:return:
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
c = conn.cursor()
|
|
||||||
print(time.strftime("%H:%M:%S"), "conn.cursor() from create_table(conn, create_table_sql)")
|
|
||||||
c.execute(create_table_sql)
|
|
||||||
except Error as e:
|
|
||||||
print(e)
|
|
||||||
|
|
||||||
# def setup_info(jid):
|
async def download_updates(db_file):
|
||||||
# def start_process(jid):
|
with create_connection(db_file) as conn:
|
||||||
async def download_updates(conn, lock):
|
|
||||||
async with lock:
|
|
||||||
print("download_updates(conn, lock)")
|
|
||||||
with conn:
|
|
||||||
# cur = conn.cursor()
|
|
||||||
# get current date
|
|
||||||
#today = date.today()
|
|
||||||
urls = await get_subscriptions(conn)
|
urls = await get_subscriptions(conn)
|
||||||
|
|
||||||
for url in urls:
|
for url in urls:
|
||||||
#"".join(url)
|
|
||||||
source = url[0]
|
source = url[0]
|
||||||
res = await download_feed(conn, source)
|
res = await download_feed(source)
|
||||||
cur = conn.cursor()
|
|
||||||
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:
|
||||||
|
with create_connection(db_file) as conn:
|
||||||
|
cur = conn.cursor()
|
||||||
cur.execute(sql, {"status": res[1], "scanned": date.today(), "url": source})
|
cur.execute(sql, {"status": res[1], "scanned": date.today(), "url": source})
|
||||||
conn.commit()
|
|
||||||
if res[0]:
|
if res[0]:
|
||||||
try:
|
try:
|
||||||
feed = feedparser.parse(res[0])
|
feed = feedparser.parse(res[0])
|
||||||
|
@ -425,8 +319,10 @@ async def download_updates(conn, lock):
|
||||||
else:
|
else:
|
||||||
valid = 1
|
valid = 1
|
||||||
sql = "UPDATE feeds SET valid = :validity WHERE address = :url"
|
sql = "UPDATE feeds SET valid = :validity WHERE address = :url"
|
||||||
|
async with DBLOCK:
|
||||||
|
with create_connection(db_file) as conn:
|
||||||
|
cur = conn.cursor()
|
||||||
cur.execute(sql, {"validity": valid, "url": source})
|
cur.execute(sql, {"validity": valid, "url": source})
|
||||||
conn.commit()
|
|
||||||
except (IncompleteReadError, IncompleteRead, error.URLError) as e:
|
except (IncompleteReadError, IncompleteRead, error.URLError) as e:
|
||||||
print(e)
|
print(e)
|
||||||
return
|
return
|
||||||
|
@ -434,14 +330,19 @@ async def download_updates(conn, lock):
|
||||||
# NOTE Need to correct the SQL statement to do so
|
# NOTE Need to correct the SQL statement to do so
|
||||||
entries = feed.entries
|
entries = feed.entries
|
||||||
length = len(entries)
|
length = len(entries)
|
||||||
|
async with DBLOCK:
|
||||||
|
with create_connection(db_file) as conn:
|
||||||
await remove_entry(conn, source, length)
|
await remove_entry(conn, source, length)
|
||||||
|
|
||||||
for entry in entries:
|
for entry in entries:
|
||||||
if entry.has_key("title"):
|
if entry.has_key("title"):
|
||||||
title = entry.title
|
title = entry.title
|
||||||
else:
|
else:
|
||||||
title = feed["feed"]["title"]
|
title = feed["feed"]["title"]
|
||||||
link = source if not entry.link else entry.link
|
link = source if not entry.link else entry.link
|
||||||
|
with create_connection(db_file) as conn:
|
||||||
exist = await check_entry(conn, title, link)
|
exist = await check_entry(conn, title, link)
|
||||||
|
|
||||||
if not exist:
|
if not exist:
|
||||||
if entry.has_key("summary"):
|
if entry.has_key("summary"):
|
||||||
summary = entry.summary
|
summary = entry.summary
|
||||||
|
@ -453,16 +354,13 @@ async def download_updates(conn, lock):
|
||||||
summary = '*** No summary ***'
|
summary = '*** No summary ***'
|
||||||
#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:
|
||||||
|
with create_connection(db_file) as conn:
|
||||||
await add_entry(conn, entry)
|
await add_entry(conn, entry)
|
||||||
await set_date(conn, source)
|
await set_date(conn, source)
|
||||||
#make_message
|
|
||||||
# message = title + '\n\n' + summary + '\n\nLink: ' + link
|
|
||||||
# print(message)
|
|
||||||
# news.append(message)
|
|
||||||
# print(len(news))
|
|
||||||
# return news
|
|
||||||
|
|
||||||
async def download_feed(conn, url):
|
|
||||||
|
async def download_feed(url):
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
async with session.get(url) as response:
|
async with session.get(url) as response:
|
||||||
status = response.status
|
status = response.status
|
||||||
|
@ -472,10 +370,8 @@ async def download_feed(conn, url):
|
||||||
else:
|
else:
|
||||||
return [False, status]
|
return [False, status]
|
||||||
|
|
||||||
loop = asyncio.get_event_loop()
|
|
||||||
loop.run_until_complete
|
|
||||||
|
|
||||||
async def check_feed(conn, lock, url):
|
async def check_feed(conn, url):
|
||||||
"""
|
"""
|
||||||
Check whether a feed exists
|
Check whether a feed exists
|
||||||
Query for feeds by url
|
Query for feeds by url
|
||||||
|
@ -483,29 +379,32 @@ async def check_feed(conn, lock, url):
|
||||||
:param url:
|
:param url:
|
||||||
:return: row
|
:return: row
|
||||||
"""
|
"""
|
||||||
async with lock:
|
|
||||||
cur = conn.cursor()
|
cur = conn.cursor()
|
||||||
print(time.strftime("%H:%M:%S"), "conn.cursor() from check_feed(conn, url)")
|
|
||||||
sql = "SELECT id FROM feeds WHERE address = ?"
|
sql = "SELECT id FROM feeds WHERE address = ?"
|
||||||
cur.execute(sql, (url,))
|
cur.execute(sql, (url,))
|
||||||
return cur.fetchone()
|
return cur.fetchone()
|
||||||
|
|
||||||
async def add_feed(conn, lock, url):
|
|
||||||
|
async def add_feed(db_file, url):
|
||||||
"""
|
"""
|
||||||
Add a new feed into the feeds table
|
Add a new feed into the feeds table
|
||||||
:param conn:
|
:param conn:
|
||||||
:param feed:
|
:param feed:
|
||||||
:return: string
|
:return: string
|
||||||
"""
|
"""
|
||||||
async with lock:
|
#TODO consider async with DBLOCK
|
||||||
print("add_feed(conn, lock, url)")
|
|
||||||
#TODO consider async with lock
|
|
||||||
#conn = create_connection(db_file)
|
#conn = create_connection(db_file)
|
||||||
cur = conn.cursor()
|
with create_connection(db_file) as conn:
|
||||||
print(time.strftime("%H:%M:%S"), "conn.cursor() from add_feed(conn, url)")
|
exist = await check_feed(conn, url)
|
||||||
exist = await check_feed(conn, lock, url)
|
|
||||||
if not exist:
|
if not exist:
|
||||||
res = await download_feed(conn, url)
|
res = await download_feed(url)
|
||||||
|
else:
|
||||||
|
return "News source is already listed in the subscription list"
|
||||||
|
|
||||||
|
async with DBLOCK:
|
||||||
|
with create_connection(db_file) as conn:
|
||||||
|
cur = conn.cursor()
|
||||||
if res[0]:
|
if res[0]:
|
||||||
feed = feedparser.parse(res[0])
|
feed = feedparser.parse(res[0])
|
||||||
if feed.bozo:
|
if feed.bozo:
|
||||||
|
@ -513,7 +412,6 @@ async def add_feed(conn, lock, url):
|
||||||
sql = """INSERT INTO feeds(address,enabled,status,valid)
|
sql = """INSERT INTO feeds(address,enabled,status,valid)
|
||||||
VALUES(?,?,?,?) """
|
VALUES(?,?,?,?) """
|
||||||
cur.execute(sql, feed)
|
cur.execute(sql, feed)
|
||||||
conn.commit()
|
|
||||||
bozo = ("WARNING: Bozo detected. Failed to load URL.")
|
bozo = ("WARNING: Bozo detected. Failed to load URL.")
|
||||||
print(bozo)
|
print(bozo)
|
||||||
return "Failed to parse URL as feed"
|
return "Failed to parse URL as feed"
|
||||||
|
@ -523,137 +421,98 @@ async def add_feed(conn, lock, url):
|
||||||
sql = """INSERT INTO feeds(name,address,enabled,status,valid)
|
sql = """INSERT INTO feeds(name,address,enabled,status,valid)
|
||||||
VALUES(?,?,?,?,?) """
|
VALUES(?,?,?,?,?) """
|
||||||
cur.execute(sql, feed)
|
cur.execute(sql, feed)
|
||||||
conn.commit()
|
|
||||||
else:
|
else:
|
||||||
feed = (url, 1, res[1], 0)
|
feed = (url, 1, res[1], 0)
|
||||||
sql = """INSERT INTO feeds(address,enabled,status,valid)
|
sql = "INSERT INTO feeds(address,enabled,status,valid) VALUES(?,?,?,?) "
|
||||||
VALUES(?,?,?,?) """
|
|
||||||
cur.execute(sql, feed)
|
cur.execute(sql, feed)
|
||||||
conn.commit()
|
|
||||||
return "Failed to get URL. HTTP Error {}".format(res[1])
|
return "Failed to get URL. HTTP Error {}".format(res[1])
|
||||||
print(time.strftime("%H:%M:%S"), "conn.commit() from add_feed(conn, url)")
|
|
||||||
# source = title if not '' else url
|
|
||||||
source = title if title else '<' + url + '>'
|
source = title if title else '<' + url + '>'
|
||||||
msg = """News source "{}" has been added to subscriptions list
|
msg = 'News source "{}" has been added to subscriptions list'.format(source)
|
||||||
""".format(source)
|
|
||||||
else:
|
|
||||||
msg = "News source is already listed in the subscription list"
|
|
||||||
return msg
|
return msg
|
||||||
|
|
||||||
async def remove_feed(conn, lock, id):
|
|
||||||
|
async def remove_feed(db_file, ix):
|
||||||
"""
|
"""
|
||||||
Delete a feed by feed id
|
Delete a feed by feed id
|
||||||
:param conn:
|
:param conn:
|
||||||
:param id: id of the feed
|
:param id: id of the feed
|
||||||
:return: string
|
:return: string
|
||||||
"""
|
"""
|
||||||
async with lock:
|
with create_connection(db_file) as conn:
|
||||||
print("remove_feed(conn, lock, id)")
|
|
||||||
# You have chose to remove feed (title, url) from your feed list.
|
|
||||||
# Enter "delete" to confirm removal.
|
|
||||||
#conn = create_connection(db_file)
|
|
||||||
cur = conn.cursor()
|
cur = conn.cursor()
|
||||||
print(time.strftime("%H:%M:%S"), "conn.cursor() from remove_feed(conn, id)")
|
|
||||||
sql = "SELECT address FROM feeds WHERE id = ?"
|
sql = "SELECT address FROM feeds WHERE id = ?"
|
||||||
# NOTE [0][1][2]
|
url = cur.execute(sql, (ix,))
|
||||||
url = cur.execute(sql, (id,))
|
|
||||||
for i in url:
|
for i in url:
|
||||||
url = i[0]
|
url = i[0]
|
||||||
sql = "DELETE FROM entries WHERE source = ?"
|
sql = "DELETE FROM entries WHERE source = ?"
|
||||||
cur.execute(sql, (url,))
|
cur.execute(sql, (url,))
|
||||||
sql = "DELETE FROM feeds WHERE id = ?"
|
sql = "DELETE FROM feeds WHERE id = ?"
|
||||||
cur.execute(sql, (id,))
|
cur.execute(sql, (ix,))
|
||||||
conn.commit()
|
|
||||||
print(time.strftime("%H:%M:%S"), "conn.commit() from remove_feed(conn, id)")
|
|
||||||
return """News source <{}> has been removed from subscriptions list
|
return """News source <{}> has been removed from subscriptions list
|
||||||
""".format(url)
|
""".format(url)
|
||||||
|
|
||||||
async def get_unread(conn, lock):
|
|
||||||
|
async def get_unread(db_file):
|
||||||
"""
|
"""
|
||||||
Check read status of entry
|
Check read status of entry
|
||||||
:param conn:
|
:param conn:
|
||||||
:param id: id of the entry
|
:param id: id of the entry
|
||||||
:return: string
|
:return: string
|
||||||
"""
|
"""
|
||||||
with conn:
|
async with DBLOCK:
|
||||||
|
with create_connection(db_file) as conn:
|
||||||
entry = []
|
entry = []
|
||||||
cur = conn.cursor()
|
cur = conn.cursor()
|
||||||
print(time.strftime("%H:%M:%S"), "conn.cursor() from get_unread(conn)")
|
|
||||||
sql = "SELECT id FROM entries WHERE read = 0"
|
sql = "SELECT id FROM entries WHERE read = 0"
|
||||||
#id = cur.execute(sql).fetchone()[0]
|
ix = cur.execute(sql).fetchone()
|
||||||
id = cur.execute(sql).fetchone()
|
if ix is None:
|
||||||
if id is None:
|
|
||||||
return False
|
return False
|
||||||
id = id[0]
|
ix = ix[0]
|
||||||
sql = "SELECT title FROM entries WHERE id = :id"
|
sql = "SELECT title FROM entries WHERE id = :id"
|
||||||
cur.execute(sql, (id,))
|
cur.execute(sql, (ix,))
|
||||||
title = cur.fetchone()[0]
|
title = cur.fetchone()[0]
|
||||||
entry.append(title)
|
entry.append(title)
|
||||||
sql = "SELECT summary FROM entries WHERE id = :id"
|
sql = "SELECT summary FROM entries WHERE id = :id"
|
||||||
cur.execute(sql, (id,))
|
cur.execute(sql, (ix,))
|
||||||
summary = cur.fetchone()[0]
|
summary = cur.fetchone()[0]
|
||||||
entry.append(summary)
|
entry.append(summary)
|
||||||
sql = "SELECT link FROM entries WHERE id = :id"
|
sql = "SELECT link FROM entries WHERE id = :id"
|
||||||
cur.execute(sql, (id,))
|
cur.execute(sql, (ix,))
|
||||||
link = cur.fetchone()[0]
|
link = cur.fetchone()[0]
|
||||||
entry.append(link)
|
entry.append(link)
|
||||||
# columns = ['title', 'summary', 'link']
|
|
||||||
# for column in columns:
|
|
||||||
# sql = "SELECT :column FROM entries WHERE id = :id"
|
|
||||||
# cur.execute(sql, {"column": column, "id": id})
|
|
||||||
# str = cur.fetchone()[0]
|
|
||||||
# entry.append(str)
|
|
||||||
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(conn, lock, id)
|
await mark_as_read(cur, ix)
|
||||||
return entry
|
return entry
|
||||||
|
|
||||||
async def mark_as_read(conn, lock, id):
|
|
||||||
|
async def mark_as_read(cur, ix):
|
||||||
"""
|
"""
|
||||||
Set read status of entry
|
Set read status of entry
|
||||||
:param conn:
|
:param cur:
|
||||||
:param id: id of the entry
|
:param ix: index of the entry
|
||||||
"""
|
"""
|
||||||
async with lock:
|
|
||||||
cur = conn.cursor()
|
|
||||||
print(time.strftime("%H:%M:%S"), "conn.cursor() from mark_as_read(conn, id)")
|
|
||||||
sql = "UPDATE entries SET summary = '', read = 1 WHERE id = ?"
|
sql = "UPDATE entries SET summary = '', read = 1 WHERE id = ?"
|
||||||
cur.execute(sql, (id,))
|
cur.execute(sql, (ix,))
|
||||||
conn.commit()
|
|
||||||
print(time.strftime("%H:%M:%S"), "conn.commit() from mark_as_read(conn, id)")
|
|
||||||
#conn.close()
|
|
||||||
|
|
||||||
async def feed_refresh(conn, lock, id):
|
|
||||||
async with lock:
|
|
||||||
cur = conn.cursor()
|
|
||||||
sql = "SELECT address FROM feeds WHERE id = :id"
|
|
||||||
cur.execute(sql, (id,))
|
|
||||||
url = cur.fetchone()[0]
|
|
||||||
res = await download_feed(conn, url)
|
|
||||||
feed = feedparser.parse(res[0])
|
|
||||||
title = feed["feed"]["title"]
|
|
||||||
sql = "UPDATE feeds SET name = :name WHERE address = :url"
|
|
||||||
cur.execute(sql, {"name": title, "url": url})
|
|
||||||
conn.commit()
|
|
||||||
|
|
||||||
# TODO mark_all_read for entries of feed
|
# TODO mark_all_read for entries of feed
|
||||||
async def toggle_status(conn, lock, id):
|
async def toggle_status(db_file, ix):
|
||||||
"""
|
"""
|
||||||
Set status of feed
|
Set status of feed
|
||||||
:param conn:
|
:param conn:
|
||||||
:param id: id of the feed
|
:param id: id of the feed
|
||||||
:return: string
|
:return: string
|
||||||
"""
|
"""
|
||||||
print("toggle_status(conn, lock, id)")
|
async with DBLOCK:
|
||||||
async with lock:
|
with create_connection(db_file) as conn:
|
||||||
#conn = create_connection(db_file)
|
|
||||||
cur = conn.cursor()
|
cur = conn.cursor()
|
||||||
print(time.strftime("%H:%M:%S"), "conn.cursor() from toggle_status(conn, id)")
|
|
||||||
sql = "SELECT name FROM feeds WHERE id = :id"
|
sql = "SELECT name FROM feeds WHERE id = :id"
|
||||||
cur.execute(sql, (id,))
|
cur.execute(sql, (ix,))
|
||||||
title = cur.fetchone()[0]
|
title = cur.fetchone()[0]
|
||||||
sql = "SELECT enabled FROM feeds WHERE id = ?"
|
sql = "SELECT enabled FROM feeds WHERE id = ?"
|
||||||
# NOTE [0][1][2]
|
# NOTE [0][1][2]
|
||||||
cur.execute(sql, (id,))
|
cur.execute(sql, (ix,))
|
||||||
status = cur.fetchone()[0]
|
status = cur.fetchone()[0]
|
||||||
# FIXME always set to 1
|
# FIXME always set to 1
|
||||||
# NOTE Maybe because is not integer
|
# NOTE Maybe because is not integer
|
||||||
|
@ -665,12 +524,11 @@ async def toggle_status(conn, lock, id):
|
||||||
status = 1
|
status = 1
|
||||||
notice = "News updates for '{}' are now enabled".format(title)
|
notice = "News updates for '{}' are now enabled".format(title)
|
||||||
sql = "UPDATE feeds SET enabled = :status WHERE id = :id"
|
sql = "UPDATE feeds SET enabled = :status WHERE id = :id"
|
||||||
cur.execute(sql, {"status": status, "id": id})
|
cur.execute(sql, {"status": status, "id": ix})
|
||||||
conn.commit()
|
|
||||||
print(time.strftime("%H:%M:%S"), "conn.commit() from toggle_status(conn, id)")
|
|
||||||
return notice
|
return notice
|
||||||
|
|
||||||
async def toggle_state(jid, state):
|
|
||||||
|
def toggle_state(jid, state):
|
||||||
"""
|
"""
|
||||||
Set status of update
|
Set status of update
|
||||||
:param jid: jid of the user
|
:param jid: jid of the user
|
||||||
|
@ -678,28 +536,22 @@ async def toggle_state(jid, state):
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
db_dir = get_default_dbdir()
|
db_dir = get_default_dbdir()
|
||||||
os.chdir(db_dir)
|
db_file = os.path.join(db_dir, r"{}.db".format(jid))
|
||||||
db_file = r"{}.db".format(jid)
|
bk_file = os.path.join(db_dir, r"{}.db.bak".format(jid))
|
||||||
bk_file = r"{}.db.bak".format(jid)
|
|
||||||
if state:
|
if state:
|
||||||
if path.exists(db_file):
|
if os.path.exists(db_file):
|
||||||
return "Updates are already enabled"
|
return "Updates are already enabled"
|
||||||
elif path.exists(bk_file):
|
elif os.path.exists(bk_file):
|
||||||
os.renames(bk_file, db_file)
|
os.renames(bk_file, db_file)
|
||||||
return "Updates are now enabled"
|
return "Updates are now enabled"
|
||||||
else:
|
else:
|
||||||
if path.exists(bk_file):
|
if os.path.exists(bk_file):
|
||||||
return "Updates are already disabled"
|
return "Updates are already disabled"
|
||||||
elif path.exists(db_file):
|
elif os.path.exists(db_file):
|
||||||
os.renames(db_file, bk_file)
|
os.renames(db_file, bk_file)
|
||||||
return "Updates are now disabled"
|
return "Updates are now disabled"
|
||||||
|
|
||||||
# if path.exists(db_file):
|
|
||||||
# os.renames(db_file, db_file + ".bak")
|
|
||||||
# break
|
|
||||||
# db_file = r"{}.db.bak".format(jid)
|
|
||||||
# if path.exists(db_file):
|
|
||||||
# os.renames(db_file, jid,+".db")
|
|
||||||
|
|
||||||
async def set_date(conn, url):
|
async def set_date(conn, url):
|
||||||
"""
|
"""
|
||||||
|
@ -709,11 +561,9 @@ async def set_date(conn, url):
|
||||||
"""
|
"""
|
||||||
today = date.today()
|
today = date.today()
|
||||||
cur = conn.cursor()
|
cur = conn.cursor()
|
||||||
print(time.strftime("%H:%M:%S"), "conn.cursor() from set_date(conn, url)")
|
|
||||||
sql = "UPDATE feeds SET updated = :today WHERE address = :url"
|
sql = "UPDATE feeds SET updated = :today WHERE address = :url"
|
||||||
cur.execute(sql, {"today": today, "url": url})
|
cur.execute(sql, {"today": today, "url": url})
|
||||||
conn.commit()
|
|
||||||
print(time.strftime("%H:%M:%S"), "conn.commit() from set_date(conn, url)")
|
|
||||||
|
|
||||||
async def get_subscriptions(conn):
|
async def get_subscriptions(conn):
|
||||||
"""
|
"""
|
||||||
|
@ -722,28 +572,26 @@ async def get_subscriptions(conn):
|
||||||
:return: rows (tuple)
|
:return: rows (tuple)
|
||||||
"""
|
"""
|
||||||
cur = conn.cursor()
|
cur = conn.cursor()
|
||||||
print(time.strftime("%H:%M:%S"), "conn.cursor() from get_subscriptions(conn)")
|
|
||||||
sql = "SELECT address FROM feeds WHERE enabled = 1"
|
sql = "SELECT address FROM feeds WHERE enabled = 1"
|
||||||
result = cur.execute(sql)
|
result = cur.execute(sql)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
async def list_subscriptions(conn):
|
|
||||||
|
async def list_subscriptions(db_file):
|
||||||
"""
|
"""
|
||||||
Query feeds
|
Query feeds
|
||||||
:param conn:
|
:param conn:
|
||||||
:return: rows (string)
|
:return: rows (string)
|
||||||
"""
|
"""
|
||||||
print("list_subscriptions(conn)")
|
with create_connection(db_file) as conn:
|
||||||
cur = conn.cursor()
|
cur = conn.cursor()
|
||||||
print(time.strftime("%H:%M:%S"), "conn.cursor() from list_subscriptions(conn)")
|
|
||||||
#sql = "SELECT id, address FROM feeds"
|
|
||||||
sql = "SELECT name, address, updated, id, enabled FROM feeds"
|
sql = "SELECT name, address, updated, id, enabled FROM feeds"
|
||||||
results = cur.execute(sql)
|
results = cur.execute(sql)
|
||||||
|
|
||||||
feeds_list = "List of subscriptions: \n"
|
feeds_list = "List of subscriptions: \n"
|
||||||
counter = 0
|
counter = 0
|
||||||
for result in results:
|
for result in results:
|
||||||
counter += 1
|
counter += 1
|
||||||
#feeds_list = feeds_list + '\n {}. {}'.format(str(result[0]), str(result[1]))
|
|
||||||
feeds_list += """\n{} \n{} \nLast updated: {} \nID: {} [{}]
|
feeds_list += """\n{} \n{} \nLast updated: {} \nID: {} [{}]
|
||||||
""".format(str(result[0]), str(result[1]), str(result[2]),
|
""".format(str(result[0]), str(result[1]), str(result[2]),
|
||||||
str(result[3]), str(result[4]))
|
str(result[3]), str(result[4]))
|
||||||
|
@ -757,48 +605,49 @@ async def list_subscriptions(conn):
|
||||||
"feed add https://reclaimthenet.org/feed/")
|
"feed add https://reclaimthenet.org/feed/")
|
||||||
return msg
|
return msg
|
||||||
|
|
||||||
async def last_entries(conn, num):
|
|
||||||
|
async def last_entries(db_file, num):
|
||||||
"""
|
"""
|
||||||
Query feeds
|
Query feeds
|
||||||
:param conn:
|
:param conn:
|
||||||
:param num: integer
|
:param num: integer
|
||||||
:return: rows (string)
|
:return: rows (string)
|
||||||
"""
|
"""
|
||||||
print("last_entries(conn, num)")
|
|
||||||
num = int(num)
|
num = int(num)
|
||||||
if num > 50:
|
if num > 50:
|
||||||
num = 50
|
num = 50
|
||||||
elif num < 1:
|
elif num < 1:
|
||||||
num = 1
|
num = 1
|
||||||
|
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 {}".format(num)
|
||||||
results = cur.execute(sql)
|
results = cur.execute(sql)
|
||||||
|
|
||||||
titles_list = "Recent {} titles: \n".format(num)
|
titles_list = "Recent {} titles: \n".format(num)
|
||||||
for result in results:
|
for result in results:
|
||||||
# titles_list += """\nTitle: {} \nLink: {}
|
titles_list += "\n{} \n{}".format(str(result[0]), str(result[1]))
|
||||||
titles_list += """\n{} \n{}
|
|
||||||
""".format(str(result[0]), str(result[1]))
|
|
||||||
return titles_list
|
return titles_list
|
||||||
|
|
||||||
async def search_entries(conn, query):
|
|
||||||
|
async def search_entries(db_file, query):
|
||||||
"""
|
"""
|
||||||
Query feeds
|
Query feeds
|
||||||
:param conn:
|
:param conn:
|
||||||
:param query: string
|
:param query: string
|
||||||
:return: rows (string)
|
:return: rows (string)
|
||||||
"""
|
"""
|
||||||
print("search_entries(conn, query)")
|
|
||||||
if len(query) < 2:
|
if len(query) < 2:
|
||||||
return "Please enter at least 2 characters to search"
|
return "Please enter at least 2 characters to search"
|
||||||
|
|
||||||
|
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".format(query)
|
||||||
# sql = "SELECT title, link FROM entries WHERE title OR link LIKE '%{}%'".format(query)
|
|
||||||
results = cur.execute(sql)
|
results = cur.execute(sql)
|
||||||
|
|
||||||
results_list = "Search results for '{}': \n".format(query)
|
results_list = "Search results for '{}': \n".format(query)
|
||||||
counter = 0
|
counter = 0
|
||||||
for result in results:
|
for result in results:
|
||||||
counter += 1
|
counter += 1
|
||||||
# titles_list += """\nTitle: {} \nLink: {}
|
|
||||||
results_list += """\n{} \n{}
|
results_list += """\n{} \n{}
|
||||||
""".format(str(result[0]), str(result[1]))
|
""".format(str(result[0]), str(result[1]))
|
||||||
if counter:
|
if counter:
|
||||||
|
@ -806,6 +655,7 @@ async def search_entries(conn, query):
|
||||||
else:
|
else:
|
||||||
return "No results found for: {}".format(query)
|
return "No results found for: {}".format(query)
|
||||||
|
|
||||||
|
|
||||||
async def check_entry(conn, title, link):
|
async def check_entry(conn, title, link):
|
||||||
"""
|
"""
|
||||||
Check whether an entry exists
|
Check whether an entry exists
|
||||||
|
@ -816,11 +666,11 @@ async def check_entry(conn, title, link):
|
||||||
:return: row
|
:return: row
|
||||||
"""
|
"""
|
||||||
cur = conn.cursor()
|
cur = conn.cursor()
|
||||||
print(time.strftime("%H:%M:%S"), "conn.cursor() from check_entry(conn, title, link)")
|
|
||||||
sql = "SELECT id FROM entries WHERE title = :title and link = :link"
|
sql = "SELECT id FROM entries WHERE title = :title and link = :link"
|
||||||
cur.execute(sql, {"title": title, "link": link})
|
cur.execute(sql, {"title": title, "link": link})
|
||||||
return cur.fetchone()
|
return cur.fetchone()
|
||||||
|
|
||||||
|
|
||||||
async def add_entry(conn, entry):
|
async def add_entry(conn, entry):
|
||||||
"""
|
"""
|
||||||
Add a new entry into the entries table
|
Add a new entry into the entries table
|
||||||
|
@ -831,10 +681,8 @@ async def add_entry(conn, entry):
|
||||||
sql = """ INSERT INTO entries(title,summary,link,source,read)
|
sql = """ INSERT INTO entries(title,summary,link,source,read)
|
||||||
VALUES(?,?,?,?,?) """
|
VALUES(?,?,?,?,?) """
|
||||||
cur = conn.cursor()
|
cur = conn.cursor()
|
||||||
print(time.strftime("%H:%M:%S"), "conn.cursor() from add_entry(conn, entry)")
|
|
||||||
cur.execute(sql, entry)
|
cur.execute(sql, entry)
|
||||||
conn.commit()
|
|
||||||
print(time.strftime("%H:%M:%S"), "conn.commit() from add_entry(conn, entry)")
|
|
||||||
|
|
||||||
async def remove_entry(conn, source, length):
|
async def remove_entry(conn, source, length):
|
||||||
"""
|
"""
|
||||||
|
@ -847,7 +695,6 @@ async def remove_entry(conn, source, length):
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
cur = conn.cursor()
|
cur = conn.cursor()
|
||||||
print(time.strftime("%H:%M:%S"), "conn.cursor() from remove_entry(conn, source, length)")
|
|
||||||
# FIXED
|
# FIXED
|
||||||
# Dino empty titles are not counted https://dino.im/index.xml
|
# Dino empty titles are not counted https://dino.im/index.xml
|
||||||
# SOLVED
|
# SOLVED
|
||||||
|
@ -856,10 +703,8 @@ async def remove_entry(conn, source, length):
|
||||||
sql = "SELECT count(id) FROM entries WHERE source = ?"
|
sql = "SELECT count(id) FROM entries WHERE source = ?"
|
||||||
count = cur.execute(sql, (source,))
|
count = cur.execute(sql, (source,))
|
||||||
count = cur.fetchone()[0]
|
count = cur.fetchone()[0]
|
||||||
#limit = count - length
|
|
||||||
limit = count - length
|
limit = count - length
|
||||||
if limit:
|
if limit:
|
||||||
#if limit > 0:
|
|
||||||
limit = limit;
|
limit = limit;
|
||||||
sql = """DELETE FROM entries WHERE id IN (
|
sql = """DELETE FROM entries WHERE id IN (
|
||||||
SELECT id FROM entries
|
SELECT id FROM entries
|
||||||
|
@ -867,20 +712,23 @@ async def remove_entry(conn, source, length):
|
||||||
ORDER BY id
|
ORDER BY id
|
||||||
ASC LIMIT :limit)"""
|
ASC LIMIT :limit)"""
|
||||||
cur.execute(sql, {"source": source, "limit": limit})
|
cur.execute(sql, {"source": source, "limit": limit})
|
||||||
conn.commit()
|
|
||||||
print(time.strftime("%H:%M:%S"), "conn.commit() from remove_entry(conn, source, length)")
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
# Setup the command line arguments.
|
# Setup the command line arguments.
|
||||||
parser = ArgumentParser(description=Slixfeed.__doc__)
|
parser = ArgumentParser(description=Slixfeed.__doc__)
|
||||||
|
|
||||||
# Output verbosity options.
|
# Output verbosity options.
|
||||||
parser.add_argument("-q", "--quiet", help="set logging to ERROR",
|
parser.add_argument(
|
||||||
|
"-q", "--quiet", help="set logging to ERROR",
|
||||||
action="store_const", dest="loglevel",
|
action="store_const", dest="loglevel",
|
||||||
const=logging.ERROR, default=logging.INFO)
|
const=logging.ERROR, default=logging.INFO
|
||||||
parser.add_argument("-d", "--debug", help="set logging to DEBUG",
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-d", "--debug", help="set logging to DEBUG",
|
||||||
action="store_const", dest="loglevel",
|
action="store_const", dest="loglevel",
|
||||||
const=logging.DEBUG, default=logging.INFO)
|
const=logging.DEBUG, default=logging.INFO
|
||||||
|
)
|
||||||
|
|
||||||
# JID and password options.
|
# JID and password options.
|
||||||
parser.add_argument("-j", "--jid", dest="jid",
|
parser.add_argument("-j", "--jid", dest="jid",
|
||||||
|
|
Loading…
Reference in a new issue