diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..112f45c --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +testfile.csv diff --git a/papis-marvin b/papis-marvin index 58a3a00..479a4da 100755 --- a/papis-marvin +++ b/papis-marvin @@ -5,13 +5,28 @@ # the iOS application 'Marvin Reader'. In the app, export your # annotations as 'csv' format and then point the script to the # resulting file. +# https://git.martyoeh.me/Marty/papis-marvin +import os import sys -from typing import List -import papis.api -import papis.commands.list -import papis.database import re -import subprocess +import logging +from typing import Dict +import papis.api +import papis.pick +import papis.format +import papis.commands.edit +import papis.commands.list +import papis.commands.add +import papis.notes +import papis.config +import papis.database +import isbnlib +import papis.isbn + +logger = logging.getLogger("marvin") +logger.setLevel(logging.DEBUG) + +DEFAULT_CSV_PATH = "/home/marty/Nextcloud/Personal/Backups/Journal.csv" def main(fpath, db): @@ -24,59 +39,74 @@ def main(fpath, db): write_to_files(notes) -def get_all_annotations(db, csv): +def get_all_annotations(db, csv) -> Dict: notes = {} note_file = "" for row in csv: - title_stripped = strip_book_title(row["Title"]) - # switch to next book if not is_same_book(row["Title"]): - documents = get_documents(db, row["Author"], title_stripped) - if not documents: - print( - f"No papis entry found for Marvin entry - {row['Author']}: {title_stripped}.\nPlease manually create." - ) + doc = get_document(db, row["Author"], row["Title"]) + if not doc: continue - note_file = get_notefile(documents) - if not note_file: - print( - f"Found reference entry but no note file for - {row['Author']}: {title_stripped}." - ) - manual_papis_entry() + note_file = get_notefile(db, doc) text = format_entry(row) if note_file and text: - if not note_file in notes.keys(): + if note_file not in notes.keys(): notes[note_file] = [] notes[note_file].append(text) return notes -# TODO Implement manual note creation -def manual_papis_entry(): - if input(f"Create note file now? [y/N] ") == "y": - # i think instead we need to run the papis.edit cmd with note bool true and maybe editor set to none? - output = subprocess.run( - ["papis", "edit", "-n"], capture_output=True, shell=True - ) - print(output) - print("NOT IMPLEMENTED: Please create note file manually.") +def get_document(db, author, title): + res = query_document(db, author, title) + if not res: + add_to_database(author, title) + res = query_document(db, author, title) + if not res: + logger.warning(f"Nothing found for {author}: {title}.\nPlease create manually.") return + return res + + +# TODO warn user/ let him pick with picker if multiple docs found +def query_document(db, author, title): + title = strip_string(title) + for query in [f"author:({author}) title:({title})"]: + print(f"query: {query}") + res = db.query(query) + if len(res) >= 1: + return res[0] + + +def add_to_database(author, title, confirm=True, edit=False): + logger.info(f"Searching - '{title} {author}'") + data = None + try: + data = papis.isbn.get_data(f"{title}") + except isbnlib.ISBNLibException as e: + logger.error(e) else: - return + logger.warning(f"Found: {data}") + if data: + papis_data = papis.isbn.data_to_papis(data[0]) + papis.commands.add.run([], data=papis_data, confirm=confirm, edit=edit) -def get_documents(db, author, title) -> List: - return db.query(f"author:({author}) title:({title})") +def get_notefile(db, document) -> str | None: + if not document.has("notes"): + notes_name = papis.config.getstring("notes-name") + document["notes"] = papis.format.format(notes_name, document) + document.save() + db.update(document) + notes_path = os.path.join(str(document.get_main_folder()), document["notes"]) -def get_notefile(document) -> str | None: - note_file = papis.commands.list.run(notes=True, documents=document) - if not note_file: - return - return str(note_file[0]) + if not os.path.exists(notes_path): + # TODO reimplement logger: logger.debug("Creating '%s'", notes_path) + papis.notes.notes_path_ensured(document) + return notes_path # TODO implement custom formatting (akin to pubs-extract) @@ -104,34 +134,30 @@ def is_same_book(title): return False -def write_to_files(notes): +def write_to_files(notes: Dict): # write to notes for f, entries in notes.items(): if f: with open(f, "a") as note: - print(f"Editing {f}...") + logger.info(f"Editing {f}...") num_added = 0 for entry in entries: with open(f) as noteread: if entry not in noteread.read(): note.write(f"{entry}\n\n") num_added += 1 - print(f"Added {num_added} entries to it.") + logger.info(f"Added {num_added} entries to it.") -title_strip_pattern = re.compile(r"([^\s\w]|_)+") +strip_pattern = re.compile(r"([^\s\w]|_)+\w*") -def strip_book_title(title) -> str: - return title_strip_pattern.sub("", title) +def strip_string(title) -> str: + return strip_pattern.sub("", title) if __name__ == "__main__": # use argument passed to command as file or default file here - fpath = ( - sys.argv[1] - if len(sys.argv) > 1 - else "/home/marty/Nextcloud/Personal/Backups/Journal.csv" - ) + fpath = sys.argv[1] if len(sys.argv) > 1 else DEFAULT_CSV_PATH main(fpath, papis.database.get())