#!/usr/bin/env python # papis-short-help: Display pretty human-readable document overview # # Takes a query and displays the metadata of the results. Uses # python-rich to display pretty panels if it exists in the environment, # otherwise displays regular text. # Can be invoked with -s to display single-line results better for # pasting into other documents. import argparse from importlib.util import find_spec from papis import database from papis.database.base import Database from papis.document import Document from dataclasses import dataclass, field parser = argparse.ArgumentParser() parser.add_argument( "--short", "-s", help="only display single-line quick info", action="store_true" ) parser.add_argument( "--url", dest="identifier", help="display identifier (doi, isbn, url) or not", action=argparse.BooleanOptionalAction, default=True, ) parser.add_argument("query", nargs="*", help="the query to search for") args = parser.parse_args() @dataclass class DocInfo: author: str = "" title: str = "" year: str = "" journal: str = "" volume: str = "" issue: str = "" pages: str = "" publisher: str = "" tags: list = field(default_factory=lambda: []) dtype: str = "" identifier: str = "" doi: str = "" @staticmethod def from_Document(doc: Document): t: list[str] | str = doc.get("tags", "") tags = ( t.replace(";", ",").replace(" ", "").split(",") if isinstance(t, str) else t ) return DocInfo( author=doc.get("author", ""), title=doc.get("title", ""), year=doc.get("year", ""), journal=doc.get("journal", ""), volume=doc.get("volume", ""), issue=doc.get("issue", ""), pages=doc.get("pages", ""), publisher=doc.get("publisher", ""), tags=tags, dtype=doc.get("type", ""), identifier=doc.get("doi", doc.get("isbn", doc.get("url", ""))), ) def main(db: Database, args) -> None: query = " ".join(args.query) docs: list[Document] = db.query(query) for doc in docs: info = DocInfo.from_Document(doc) if args.short: print_short(info, with_identifier=args.identifier) else: print_info(info, with_identifier=args.identifier) def print_short(doc: DocInfo, with_identifier: bool = True) -> None: print( f"{doc.author} ({doc.year}). {doc.title}. " f"{doc.identifier if with_identifier else ''}\n" ) def print_info(doc: DocInfo, with_identifier: bool = True) -> None: if find_spec("rich"): from rich import print as richprint from rich.panel import Panel info: str = ( f"[red]{doc.author}[/red] ({doc.year}) " f"[steel_blue]\\[{doc.dtype}][/steel_blue]\n" f"[bold]{doc.title}[/bold]\n" f"{doc.journal} ({doc.volume}/{doc.issue}){doc.pages} - {doc.publisher}\n" f"[grey69]{[tag for tag in doc.tags]} " ) if with_identifier: info += f"[link={doc.identifier}]{doc.identifier}[/link][/grey69]" richprint(Panel(info, expand=False)) else: info: str = ( f"{doc.author} ({doc.year}) " f"[{doc.dtype}]\n" f"{doc.title}\n" f"{doc.journal} ({doc.volume}/{doc.issue}){doc.pages} - {doc.publisher}\n" f"{[tag for tag in doc.tags]} " f"{doc.identifier}" if with_identifier else "" ) print(f"{info}\n---") if __name__ == "__main__": main(database.get(), args)