Files
zulip/zerver/lib/narrow_helpers.py
PieterCK 3773ba10e1 url_decoding: Add parse_narrow_url.
This adds the Python copy of `hash_util.parse_narrow`. In the web app,
it will mainly be used in the import process later on. So, although it
has the same purpose as its frontend twin, there are differences:

- This doesn't convert a user-id-slug into a list of user emails. It
will instead parse it into a list of user IDs, as that is the preferred
form for those kinds of operators. It will also help in later operations
to remap the object IDs during import.

- To the same effect as the first point, operands can be an actual list
or int instead of a list or int as a string (e.g., "12,14,15" or "93").

- It has fewer validations than its frontend counterpart. It doesn't
look up the parsed object IDs for validity. This is partly because of
its main use case in import.
2025-02-24 15:37:40 -08:00

64 lines
1.6 KiB
Python

"""
This module partly exists to prevent circular dependencies.
It also isolates some fairly yucky code related to the fact
that we have to support two formats of narrow specifications
from users:
legacy:
[["stream", "devel"], ["is", mentioned"]
modern:
[
{"operator": "stream", "operand": "devel", "negated": "false"},
{"operator": "is", "operand": "mentioned", "negated": "false"},
]
And then on top of that, we want to represent narrow
specification internally as dataclasses.
"""
import os
from collections.abc import Collection, Sequence
from dataclasses import dataclass, field
from django.conf import settings
@dataclass
class NarrowTerm:
operator: str
operand: str | int | list[int]
negated: bool
@dataclass
class NeverNegatedNarrowTerm(NarrowTerm):
negated: bool = field(default=False, init=False)
operand: str
def narrow_dataclasses_from_tuples(
tups: Collection[Sequence[str]],
) -> Collection[NeverNegatedNarrowTerm]:
"""
This method assumes that the callers are in our event-handling codepath, and
therefore as of summer 2023, they do not yet support the "negated" flag.
"""
return [NeverNegatedNarrowTerm(operator=tup[0], operand=tup[1]) for tup in tups]
stop_words_list: list[str] | None = None
def read_stop_words() -> list[str]:
global stop_words_list
if stop_words_list is None:
file_path = os.path.join(
settings.DEPLOY_ROOT, "puppet/zulip/files/postgresql/zulip_english.stop"
)
with open(file_path) as f:
stop_words_list = f.read().splitlines()
return stop_words_list