Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ exclude: ^src/reader/_vendor/.*$
repos:

- repo: https://github.com/pycqa/isort
rev: 7.0.0
rev: 8.0.1
hooks:
- id: isort

Expand All @@ -14,7 +14,7 @@ repos:
args: ["--py311-plus"]

- repo: https://github.com/psf/black-pre-commit-mirror
rev: 25.12.0
rev: 26.3.1
hooks:
- id: black
args: ["-S"]
Expand Down
2 changes: 0 additions & 2 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import packaging.version
from setuptools.config.pyprojecttoml import read_configuration


sys.path.insert(0, os.path.abspath('../src'))

# mock some things "by hand", so we can import reader below without any dependencies
Expand All @@ -25,7 +24,6 @@

import reader


extensions = [
'sphinx_rtd_theme',
'sphinx.ext.autodoc',
Expand Down
1 change: 0 additions & 1 deletion examples/podcast.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@

from reader import make_reader


feed_url = "http://www.hellointernet.fm/podcast?format=rss"
podcasts_dir = "podcasts"

Expand Down
1 change: 0 additions & 1 deletion scripts/bench.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@

import click


root_dir = os.path.dirname(__file__)
sys.path.insert(0, os.path.join(root_dir, '../src'))
sys.path.insert(0, os.path.join(root_dir, '../tests'))
Expand Down
1 change: 0 additions & 1 deletion scripts/debug_storage_stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
import numpy as np
from tabulate import tabulate


# assumes dict()s are ordered

value_funcs = {
Expand Down
1 change: 0 additions & 1 deletion scripts/entry_dedupe_backtest.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
from reader import make_reader
from reader.plugins import entry_dedupe


DB_ARCHIVE = "_backups/reader.sqlite.2025-10-04.gz"

file = sys.argv[1]
Expand Down
2 changes: 0 additions & 2 deletions scripts/jscontrols.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,12 @@
from flask import redirect
from flask import request


root_dir = os.path.dirname(__file__)
sys.path.insert(0, os.path.join(root_dir, '../src'))

from reader._app.api_thing import APIError
from reader._app.api_thing import APIThing


app = Flask(
__name__,
template_folder='../src/reader/_app/templates',
Expand Down
1 change: 0 additions & 1 deletion scripts/vendor_app_stuff.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

import requests


STUFF = {
"htmx.org@2.0.8": ["dist/htmx.min.js"],
"htmx-ext-response-targets@2.0.4": ["dist/response-targets.min.js"],
Expand Down
1 change: 0 additions & 1 deletion src/reader/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@
ReaderWarning as ReaderWarning,
)


# Constants.

USER_AGENT = f'python-reader/{__version__} (+https://github.com/lemon24/reader)'
Expand Down
1 change: 0 additions & 1 deletion src/reader/__main__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import sys


CANNOT_IMPORT = """\
Error: cannot import reader._cli

Expand Down
1 change: 0 additions & 1 deletion src/reader/_app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
from .forms import EntryFilter
from .forms import FeedFilter


# for a prototype with tags and search support, see
# https://github.com/lemon24/reader/tree/3.21/src/reader/_app/v2

Expand Down
1 change: 0 additions & 1 deletion src/reader/_app/ext.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
from reader import make_reader
from reader.plugins._loader import PluginLoader


_plugin_loader = PluginLoader('init_app')


Expand Down
1 change: 0 additions & 1 deletion src/reader/_app/legacy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@
from .api_thing import APIError
from .api_thing import APIThing


blueprint = Blueprint(
'reader', __name__, static_folder='static', template_folder='templates'
)
Expand Down
1 change: 0 additions & 1 deletion src/reader/_app/legacy/wsgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import reader._app.legacy
import reader._cli


config = reader._cli.load_reader_config()
app = reader._app.legacy.create_app(config)
app.config['TRAP_BAD_REQUEST_ERRORS'] = bool(
Expand Down
1 change: 0 additions & 1 deletion src/reader/_app/wsgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import reader._app
import reader._cli


config = reader._cli.load_reader_config()
app = reader._app.create_app(config)
app.config['TRAP_BAD_REQUEST_ERRORS'] = bool(
Expand Down
1 change: 0 additions & 1 deletion src/reader/_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
from ._config_utils import load_config_from_context
from .plugins._loader import PluginLoader


app_name = reader.__name__
app_dir = click.get_app_dir(app_name)

Expand Down
1 change: 0 additions & 1 deletion src/reader/_hash_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
from collections.abc import Collection
from typing import Any


# The first byte of the hash contains its version,
# to allow upgrading the implementation without changing existing hashes.
# (In practice, it's likely we'll just let the hash change and update
Expand Down
1 change: 0 additions & 1 deletion src/reader/_parser/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
from .requests import SessionFactory
from .requests import TimeoutType


if TYPE_CHECKING: # pragma: no cover
from werkzeug.datastructures import RequestCacheControl

Expand Down
1 change: 0 additions & 1 deletion src/reader/_parser/_http_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
from werkzeug.datastructures import MIMEAccept
from werkzeug.datastructures import ResponseCacheControl


parse_options_header = werkzeug.http.parse_options_header
parse_accept_header = werkzeug.http.parse_accept_header
parse_date = werkzeug.http.parse_date
Expand Down
1 change: 0 additions & 1 deletion src/reader/_parser/_lazy.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
from ._url_utils import normalize_url
from .requests import SessionFactory


log = logging.getLogger('reader')


Expand Down
1 change: 0 additions & 1 deletion src/reader/_parser/feedparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
from ._http_utils import parse_accept_header
from ._http_utils import unparse_accept_header


if os.environ.get('READER_NO_VENDORED_FEEDPARSER', '') not in ('', '0'):
import feedparser # type: ignore
else:
Expand Down
1 change: 0 additions & 1 deletion src/reader/_parser/jsonfeed.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
from ..types import Content
from ..types import Enclosure


if TYPE_CHECKING: # pragma: no cover
from . import FeedAndEntries
from .requests import Headers
Expand Down
1 change: 0 additions & 1 deletion src/reader/_parser/requests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@

from ..._utils import lazy_import


if TYPE_CHECKING: # pragma: no cover
import requests

Expand Down
1 change: 0 additions & 1 deletion src/reader/_parser/requests/_lazy.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
from . import CachingInfo
from . import TimeoutType


if TYPE_CHECKING: # pragma: no cover
from . import Headers
from . import RequestHook
Expand Down
1 change: 0 additions & 1 deletion src/reader/_plugins/legacy/enclosure_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
from flask import url_for
from jinja2.filters import do_striptags as striptags


blueprint = Blueprint('enclosure_tags', __name__)


Expand Down
1 change: 0 additions & 1 deletion src/reader/_plugins/legacy/preview_feed_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
from reader._app.legacy import get_reader
from reader._app.legacy import got_preview_parse_error


blueprint = Blueprint('preview_feed_list', __name__, template_folder='templates')


Expand Down
1 change: 0 additions & 1 deletion src/reader/_plugins/legacy/share.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
from urllib.parse import quote
from urllib.parse import urlparse


TEMPLATES = {
'Twitter': "https://twitter.com/share?text={title}&url={url}",
'HN': "https://news.ycombinator.com/submitlink?u={url}&t={title}",
Expand Down
1 change: 0 additions & 1 deletion src/reader/_plugins/sqlite_releases.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
from reader._types import EntryData
from reader._types import FeedData


warnings.filterwarnings(
'ignore',
message='No parser was explicitly specified',
Expand Down
1 change: 0 additions & 1 deletion src/reader/_storage/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
from ._feeds import FeedsMixin
from ._tags import TagsMixin


# Row value support was added in 3.15.
# pragma_*() tabled-valued functions were added in 3.16.
# last_insert_rowid() support for FTS5 was added in 3.18.
Expand Down
1 change: 0 additions & 1 deletion src/reader/_storage/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
from ._sql_utils import paginated_query
from ._sql_utils import Query


APPLICATION_ID = b'read'

_T = TypeVar('_T')
Expand Down
7 changes: 2 additions & 5 deletions src/reader/_storage/_changes.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
from ._sql_utils import Query
from ._sqlite_utils import ddl_transaction


if TYPE_CHECKING: # pragma: no cover
from ._base import StorageBase

Expand Down Expand Up @@ -41,12 +40,10 @@ def _enable(cls, db: sqlite3.Connection) -> None:
for object in objects.values():
object.create(db)
db.execute("UPDATE entries SET sequence = randomblob(16)")
db.execute(
"""
db.execute("""
INSERT INTO changes
SELECT sequence, feed, id, '', 1 FROM entries
"""
)
""")

@wrap_exceptions()
def disable(self) -> None:
Expand Down
18 changes: 4 additions & 14 deletions src/reader/_storage/_entries.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
from ._tags import entry_tags_filter
from ._tags import feed_tags_filter


if TYPE_CHECKING: # pragma: no cover
from ._base import StorageBase
else:
Expand Down Expand Up @@ -404,10 +403,7 @@ def set_entry_recent_sort(
def get_entries_query(
filter: EntryFilter, sort: EntrySort
) -> tuple[Query, dict[str, Any]]:
query = (
Query()
.SELECT(
*"""
query = Query().SELECT(*"""
entries.feed
feeds.updated
feeds.title
Expand Down Expand Up @@ -441,11 +437,7 @@ def get_entries_query(
entries.last_updated
entries.original_feed
entries.sequence
""".split()
)
.FROM("entries")
.JOIN("feeds ON feeds.url = entries.feed")
)
""".split()).FROM("entries").JOIN("feeds ON feeds.url = entries.feed")
context = entry_filter(query, filter)
ENTRIES_SORT[sort](query)
return query, context
Expand Down Expand Up @@ -540,13 +532,11 @@ def entry_filter(
add(TRISTATE_FILTER_TO_SQL[important].format(expr='entries.important'))

if has_enclosures is not None:
add(
f"""
add(f"""
{'NOT' if has_enclosures else ''}
(json_array_length(entries.enclosures) IS NULL
OR json_array_length(entries.enclosures) = 0)
"""
)
""")

if source_url:
add("json_extract(entries.source, '$.url') = :source_url")
Expand Down
1 change: 0 additions & 1 deletion src/reader/_storage/_feeds.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
from ._sqlite_utils import rowcount_exactly_one
from ._tags import feed_tags_filter


if TYPE_CHECKING: # pragma: no cover
from ._base import StorageBase
else:
Expand Down
1 change: 0 additions & 1 deletion src/reader/_storage/_html_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import warnings
from typing import TYPE_CHECKING


if TYPE_CHECKING: # pragma: no cover
import bs4

Expand Down
13 changes: 4 additions & 9 deletions src/reader/_storage/_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from ._sqlite_utils import ddl_transaction
from ._sqlite_utils import HeavyMigration


SCHEMA = parse_schema("""

CREATE TABLE feeds (
Expand Down Expand Up @@ -153,12 +152,10 @@ def create_indexes(db: sqlite3.Connection) -> None:
def update_from_36_to_37(db: sqlite3.Connection, /) -> None: # pragma: no cover
# for https://github.com/lemon24/reader/issues/279
db.execute("ALTER TABLE entries ADD COLUMN recent_sort TIMESTAMP;")
db.execute(
"""
db.execute("""
UPDATE entries
SET recent_sort = coalesce(published, updated, first_updated_epoch);
"""
)
""")
db.execute("DROP INDEX entries_by_kinda_first_updated;")
db.execute("DROP INDEX entries_by_kinda_published;")
entries_by_recent_index.create(db)
Expand All @@ -168,8 +165,7 @@ def update_from_37_to_38(db: sqlite3.Connection, /) -> None: # pragma: no cover
# https://github.com/lemon24/reader/issues/254#issuecomment-1404215814

entries_table.create(db, 'new_entries')
db.execute(
"""
db.execute("""
INSERT INTO new_entries (
id,
feed,
Expand Down Expand Up @@ -226,8 +222,7 @@ def update_from_37_to_38(db: sqlite3.Connection, /) -> None: # pragma: no cover
feed_order,
recent_sort
FROM entries;
"""
)
""")

# IMPORTANT: this drops ALL indexes and triggers ON entries
db.execute("DROP TABLE entries;")
Expand Down
Loading
Loading