chore: Fix for additional linting rules
This commit is contained in:
parent
96cd4929c9
commit
f5455b6946
7 changed files with 58 additions and 40 deletions
|
|
@ -1,4 +1,9 @@
|
|||
import re
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from papis_extract.annotation import Annotation
|
||||
from papis_extract.exporter import Exporter
|
||||
|
||||
import click
|
||||
import papis.cli
|
||||
|
|
@ -9,8 +14,6 @@ import papis.strings
|
|||
from papis.document import Document
|
||||
|
||||
from papis_extract import extraction
|
||||
from papis_extract.annotation import Annotation
|
||||
from papis_extract.exporter import Exporter
|
||||
from papis_extract.exporters import all_exporters
|
||||
from papis_extract.extractors import all_extractors
|
||||
from papis_extract.formatter import Formatter, formatters
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import math
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, Optional, cast
|
||||
from typing import Any, cast
|
||||
|
||||
import chevron
|
||||
import papis.config
|
||||
|
|
@ -117,7 +117,7 @@ class Annotation:
|
|||
return color_mapping.get(colorname, "")
|
||||
|
||||
# mimics the functions in papis.config.{getlist,getint,getfloat} etc.
|
||||
def _getdict(self, key: str, section: Optional[str] = None) -> dict[str, str]:
|
||||
def _getdict(self, key: str, section: str | None = None) -> dict[str, str]:
|
||||
"""Dict getter
|
||||
|
||||
:returns: A python dict
|
||||
|
|
@ -126,19 +126,17 @@ class Annotation:
|
|||
"""
|
||||
rawvalue: Any = papis.config.general_get(key, section=section)
|
||||
if isinstance(rawvalue, dict):
|
||||
return cast(dict[str, str], rawvalue)
|
||||
return cast("dict[str, str]", rawvalue)
|
||||
try:
|
||||
rawvalue = eval(rawvalue)
|
||||
except Exception:
|
||||
raise SyntaxError(
|
||||
"The key '{}' must be a valid Python object: {}".format(key, rawvalue)
|
||||
f"The configuration key '{key}' must be a valid Python dict: {rawvalue}"
|
||||
)
|
||||
else:
|
||||
if not isinstance(rawvalue, dict):
|
||||
raise SyntaxError(
|
||||
"The key '{}' must be a valid Python dict. Got: {} (type {!r})".format(
|
||||
key, rawvalue, type(rawvalue).__name__
|
||||
)
|
||||
f"The configuration key '{key}' must be a valid Python dict. Got: {rawvalue} (type {type(rawvalue).__name__})"
|
||||
)
|
||||
|
||||
return cast(dict[str, str], rawvalue)
|
||||
return cast("dict[str, str]", rawvalue)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
|
||||
import Levenshtein
|
||||
import papis.commands.edit
|
||||
|
|
@ -69,11 +70,11 @@ class NotesExporter:
|
|||
:type duplicates: bool, optional
|
||||
"""
|
||||
logger.debug("Adding annotations to note...")
|
||||
notes_path = papis.notes.notes_path_ensured(document)
|
||||
notes_path = Path(papis.notes.notes_path_ensured(document))
|
||||
|
||||
existing: list[str] = []
|
||||
with open(notes_path, "r") as file_read:
|
||||
existing = file_read.readlines()
|
||||
with notes_path.open("r") as fr:
|
||||
existing = fr.readlines()
|
||||
|
||||
new_annotations: list[str] = formatted_annotations
|
||||
if not duplicates:
|
||||
|
|
@ -81,15 +82,16 @@ class NotesExporter:
|
|||
formatted_annotations, existing
|
||||
)
|
||||
if not new_annotations:
|
||||
logger.debug("No new annotations to be added.")
|
||||
return
|
||||
|
||||
with open(notes_path, "a") as f:
|
||||
with notes_path.open("a") as fa:
|
||||
# add newline if theres no empty space at file end
|
||||
if len(existing) > 0 and existing[-1].strip() != "":
|
||||
f.write("\n")
|
||||
fa.write("\n")
|
||||
# We filter out any empty lines from the annotations
|
||||
filtered_annotations = [annot for annot in new_annotations if annot != ""]
|
||||
f.write("\n\n".join(filtered_annotations))
|
||||
fa.write("\n\n".join(filtered_annotations))
|
||||
logger.info(
|
||||
f"Wrote {len(filtered_annotations)} "
|
||||
f"{'line' if len(filtered_annotations) == 1 else 'lines'} "
|
||||
|
|
@ -97,11 +99,11 @@ class NotesExporter:
|
|||
)
|
||||
|
||||
if git:
|
||||
msg = "Update notes for '{0}'".format(papis.document.describe(document))
|
||||
msg = f"Update annotations for '{papis.document.describe(document)}'"
|
||||
folder = document.get_main_folder()
|
||||
if folder:
|
||||
papis.git.add_and_commit_resources(
|
||||
folder, [notes_path, document.get_info_file()], msg
|
||||
folder, [str(notes_path), document.get_info_file()], msg
|
||||
)
|
||||
|
||||
def _drop_existing_annotations(
|
||||
|
|
|
|||
|
|
@ -19,9 +19,7 @@ class PdfExtractor:
|
|||
if not filename.is_file():
|
||||
logger.error(f"File {str(filename)} not readable.")
|
||||
return False
|
||||
if not self._is_pdf(filename):
|
||||
return False
|
||||
return True
|
||||
return self._is_pdf(filename)
|
||||
|
||||
def run(self, filename: Path) -> list[Annotation]:
|
||||
"""Extract annotations from a file.
|
||||
|
|
@ -39,15 +37,15 @@ class PdfExtractor:
|
|||
if not quote and not note:
|
||||
continue
|
||||
color: tuple[float, float, float] = cast(
|
||||
tuple[float, float, float],
|
||||
"tuple[float, float, float]",
|
||||
(
|
||||
annot.colors.get("fill")
|
||||
or annot.colors.get("stroke")
|
||||
or (0.0, 0.0, 0.0)
|
||||
),
|
||||
)
|
||||
page_nr: int = cast(int, page.number or 0)
|
||||
highlight_type: str = cast(str, annot.type[1] or "")
|
||||
page_nr: int = cast("int", page.number or 0)
|
||||
highlight_type: str = cast("str", annot.type[1] or "")
|
||||
a = Annotation(
|
||||
file=str(filename),
|
||||
content=quote or "",
|
||||
|
|
@ -83,7 +81,7 @@ class PdfExtractor:
|
|||
should both be included or are the same, using
|
||||
Levenshtein distance.
|
||||
"""
|
||||
content = cast(str, annotation.info["content"].replace("\n", " "))
|
||||
content = cast("str", annotation.info["content"].replace("\n", " "))
|
||||
written = page.get_textbox(annotation.rect).replace("\n", " ")
|
||||
|
||||
# highlight with selection in note
|
||||
|
|
@ -94,13 +92,13 @@ class PdfExtractor:
|
|||
if Levenshtein.ratio(content, written) > minimum_similarity:
|
||||
return (content, None)
|
||||
# both a highlight and a note
|
||||
elif content and written:
|
||||
if content and written:
|
||||
return (written, content)
|
||||
# an independent note, not a highlight
|
||||
elif content:
|
||||
if content:
|
||||
return (None, content)
|
||||
# highlight with selection not in note
|
||||
elif written:
|
||||
if written:
|
||||
return (written, None)
|
||||
# just a highlight without any text
|
||||
return (None, None)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
from pathlib import Path
|
||||
|
||||
import magic
|
||||
import papis.config
|
||||
import papis.logging
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
|
|
@ -13,7 +12,7 @@ logger = papis.logging.get_logger(__name__)
|
|||
|
||||
class PocketBookExtractor:
|
||||
def can_process(self, filename: Path) -> bool:
|
||||
if not magic.from_file(filename, mime=True) == "text/xml":
|
||||
if magic.from_file(filename, mime=True) != "text/xml":
|
||||
return False
|
||||
|
||||
content = self._read_file(filename)
|
||||
|
|
@ -21,11 +20,11 @@ class PocketBookExtractor:
|
|||
return False
|
||||
|
||||
html = BeautifulSoup(content, features="xml")
|
||||
if not html.find(
|
||||
"meta", {"name": "generator", "content": "PocketBook Bookmarks Export"}
|
||||
):
|
||||
return False
|
||||
return True
|
||||
return bool(
|
||||
html.find(
|
||||
"meta", {"name": "generator", "content": "PocketBook Bookmarks Export"}
|
||||
)
|
||||
)
|
||||
|
||||
def run(self, filename: Path) -> list[Annotation]:
|
||||
"""Extract annotations from pocketbook html file.
|
||||
|
|
@ -78,8 +77,8 @@ class PocketBookExtractor:
|
|||
|
||||
def _read_file(self, filename: Path) -> str:
|
||||
try:
|
||||
with open(filename) as f:
|
||||
return f.read()
|
||||
with filename.open("r") as fr:
|
||||
return fr.read()
|
||||
except FileNotFoundError:
|
||||
logger.error(f"Could not open file {filename} for extraction.")
|
||||
return ""
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ class ReadEraExtractor:
|
|||
"""
|
||||
|
||||
def can_process(self, filename: Path) -> bool:
|
||||
if not magic.from_file(filename, mime=True) == "text/plain":
|
||||
if magic.from_file(filename, mime=True) != "text/plain":
|
||||
return False
|
||||
|
||||
content = self._read_file(filename)
|
||||
|
|
@ -83,8 +83,8 @@ class ReadEraExtractor:
|
|||
|
||||
def _read_file(self, filename: Path) -> list[str]:
|
||||
try:
|
||||
with open(filename, encoding="utf-8") as f:
|
||||
return f.readlines()
|
||||
with filename.open("r") as fr:
|
||||
return fr.readlines()
|
||||
except FileNotFoundError:
|
||||
logger.error(f"Could not open file {filename} for extraction.")
|
||||
return []
|
||||
|
|
|
|||
|
|
@ -39,6 +39,24 @@ pocketbook = ["beautifulsoup4<5.0.0,>=4.12.3"]
|
|||
[tool.uv]
|
||||
dev-dependencies = ["pytest<9.0.0,>=8.0.0", "pytest-cov<7.0.0,>=6.0.0"]
|
||||
|
||||
[tool.ruff.lint]
|
||||
extend-select = [
|
||||
"C4", # Catch incorrect use of comprehensions, dict, list, etc
|
||||
"F", # Pyflakes rules
|
||||
"FA", # Enforce from __future__ import annotations
|
||||
"I", # Sort imports properly
|
||||
"ICN", # Use common import conventions
|
||||
"ISC", # Good use of string concatenation
|
||||
"NPY", # Some numpy-specific things
|
||||
"PTH", # Use pathlib instead of os.path
|
||||
"RET", # Good return practices
|
||||
"SIM", # Common simplification rules
|
||||
"TC", # Enforce importing certain types in a TYPE_CHECKING block
|
||||
"TID", # Some good import practices
|
||||
"UP", # Warn if certain things can changed due to newer Python versions
|
||||
"W", # PyCodeStyle warnings
|
||||
]
|
||||
|
||||
[build-system]
|
||||
requires = ["hatchling"]
|
||||
build-backend = "hatchling.build"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue