From dc4b5f819e38fbca23c72d0058a82567b829650f Mon Sep 17 00:00:00 2001 From: Emanuele Date: Fri, 5 Jun 2020 16:20:19 +0100 Subject: [PATCH] Preparing for release --- README.md | 13 ++-- sublime_evernote.py | 158 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 161 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 5a42f32..0f34a16 100644 --- a/README.md +++ b/README.md @@ -32,18 +32,13 @@ See [Commands](#commands) and the [wiki] for details. ## What's new -**v2.7.2** +**v2.7.3** -+ Fix: patching Evernote's SDK to make it compatible with ST 3126 on Linux (fixes #150) ++ Fix: patching Evernote's SDK to fix an issue due to undocumented changes in API (fixes #216) -**v2.7.1** +**v2.7.2** -+ Fix: solved incompatibility with [Markdown Preview](https://packagecontrol.io/packages/Markdown%20Preview) plugin (fixes #119) -+ Fix: multiple metadata headers now supported (thanks [@xdutaotao](https://github.com/bordaigorl/sublime-evernote/issues/127#issuecomment-208210297)) -+ Fix: long CSS for body now properly supported (fixes #128) -+ Fix: url/filepath detection fixed for Windows (fixes #137, thanks @358463121) -+ **Open note**: accept links as `note_guid` and offer options to load from clipboard/prompt (see [wiki](https://github.com/bordaigorl/sublime-evernote/wiki/The-Open-Note-Command)) -+ **Insert Note Link**: now accepts `template` and `to` arguments ++ Fix: patching Evernote's SDK to make it compatible with ST 3126 on Linux (fixes #150) See the [Changelog](https://github.com/bordaigorl/sublime-evernote/wiki/Changelog) for the full list. diff --git a/sublime_evernote.py b/sublime_evernote.py index 2c314eb..a070bb8 100644 --- a/sublime_evernote.py +++ b/sublime_evernote.py @@ -41,7 +41,7 @@ from base64 import b64encode, b64decode -EVERNOTE_PLUGIN_VERSION = "2.7.2" +EVERNOTE_PLUGIN_VERSION = "2.7.3" USER_AGENT = {'User-Agent': 'SublimeEvernote/' + EVERNOTE_PLUGIN_VERSION} EVERNOTE_SETTINGS = "Evernote.sublime-settings" @@ -942,6 +942,162 @@ def do_open_note(self, guid, convert=True, **unk_args): sublime.error_message(explain_error(e)) +class OpenEvernoteNotesCommand(EvernoteDoWindow): + + def do_run(self, note_guid=None, by_searching=None, + from_notebook=None, with_tags=None, + order=None, ascending=None, max_notes=None, **kwargs): + notebooks = self.get_notebooks() + + search_args = {} + + order = order or self.settings.get("notes_order", "default").upper() + search_args['order'] = Types.NoteSortOrder._NAMES_TO_VALUES.get(order.upper()) # None = default + search_args['ascending'] = ascending or self.settings.get("notes_order_ascending", False) + + if from_notebook: + try: + search_args['notebookGuid'] = self.notebook_from_name(from_notebook).guid + except: + sublime.error_message("Notebook %s not found!" % from_notebook) + return + + if with_tags: + if isinstance(with_tags, str): + with_tags = [with_tags] + try: + search_args['tagGuids'] = [self.tag_from_name(name) for name in with_tags] + except KeyError as e: + sublime.error_message("Tag %s not found!" % e) + + def notes_panel(notes, show_notebook=False): + if not notes: + self.message("No notes found!") # Should it be a dialog? + return + + for note in notes: + self.message('Retrieving note "%s"...' % note.title) + self.open_note(note.guid, **kwargs) + + def on_notebook(notebook): + if notebook < 0: + return + search_args['notebookGuid'] = notebooks[notebook].guid + notes = self.find_notes(search_args, max_notes) + async_do(lambda: notes_panel(notes), "Fetching notes list", done_msg=None) + + def do_search(query): + self.message("Searching notes...") + search_args['words'] = query + async_do(lambda: notes_panel(self.find_notes(search_args, max_notes), True), "Fetching notes list", done_msg=None) + + if note_guid: + if note_guid == "prompt": + self.window.show_input_panel("Note GUID or link:", "", lambda x: self.open_note(x, **kwargs), None, None) + return + elif note_guid == "clipboard": + note_guid = sublime.get_clipboard(2000) + + self.open_note(note_guid, **kwargs) + return + + if by_searching: + if isinstance(by_searching, str): + do_search(by_searching) + else: + p = self.window.show_input_panel("Enter search query:", "", do_search, None, None) + if isinstance(by_searching, dict): + p.run_command("insert_snippet", {"contents": by_searching.get("snippet", "")}) + return + if from_notebook or with_tags: + notes_panel(self.find_notes(search_args, max_notes), not from_notebook) + elif len(notebooks) == 1: + on_notebook(0) + else: + if self.settings.get("show_stacks", True): + menu = ["%s ยป %s" % (nb.stack, nb.name) if nb.stack else nb.name for nb in notebooks] + else: + menu = [nb.name for nb in notebooks] + self.window.show_quick_panel(menu, on_notebook) + + def find_notes(self, search_args, max_notes=None): + return self.get_note_store().findNotesMetadata( + self.token(), + NoteStore.NoteFilter(**search_args), + None, max_notes or self.settings.get("max_notes", 100), + NoteStore.NotesMetadataResultSpec(includeTitle=True, includeNotebookGuid=True)).notes + + def open_note(self, guid, convert=True, **unk_args): + try: + guid = guid.strip().split('/')[-1] + except Exception: + pass + async_do(lambda: self.do_open_note(guid, convert, **unk_args), "Retrieving note") + + def do_open_note(self, guid, convert=True, **unk_args): + try: + noteStore = self.get_note_store() + note = noteStore.getNote(self.token(), guid, True, False, False, False) + nb_name = self.notebook_from_guid(note.notebookGuid).name + LOG(note.content) + LOG(note.guid) + if convert: + # tags = [noteStore.getTag(self.token(), guid).name for guid in (note.tagGuids or [])] + # tags = [self.tag_from_guid(guid) for guid in (note.tagGuids or [])] + tags = noteStore.getNoteTagNames(self.token(), note.guid) + meta = metadata_header(note.title, tags, nb_name) + body_start = note.content.find('', body_start) + 1 + builtin = note.content.find(SUBLIME_EVERNOTE_COMMENT_BEG, body_start, body_start+100) + if builtin >= 0: + try: + builtin_end = note.content.find(SUBLIME_EVERNOTE_COMMENT_END, builtin) + bmdtxt = note.content[builtin+len(SUBLIME_EVERNOTE_COMMENT_BEG):builtin_end] + mdtxt = b64decode(bmdtxt.encode('utf8')).decode('utf8') + parts = extract_metadata(mdtxt) + if parts["metadata"]: + if parts["metadata"].get("title") == note.title and \ + "tags" in parts["metadata"] and \ + set(parts["metadata"].get("tags")) == set(tags) and \ + parts["metadata"].get("notebook") == nb_name: + meta = "" + else: + LOG("Overridding metadata") + mdtxt = parts["contents"] + LOG("Loaded from built-in comment") + except Exception as e: + mdtxt = "" + LOG("Loading from built-in comment failed", e) + if builtin < 0 or mdtxt == "": + try: + mdtxt = html2text.html2text(note.content) + LOG("Conversion ok") + except Exception as e: + mdtxt = note.content + LOG("Conversion failed", e) + + newview = self.window.new_file() + syntax = 'Packages/MarkdownEditing/Markdown.sublime-syntax' + note_contents = meta+mdtxt + else: + newview = self.window.new_file() + syntax = find_syntax("XML") + note_contents = note.content + newview.set_syntax_file(syntax) + newview.set_scratch(True) + replace_view_text(newview, note_contents) + newview.set_name(note.title) + newview.settings().set("$evernote_guid", note.guid) + self.message('Note "%s" opened!' % note.title) + self.update_status_info(note, newview) + # note_is_current(newview) + except Exception as e: + sublime.error_message(explain_error(e)) + + class AttachToEvernoteNote(OpenEvernoteNoteCommand): def open_note(self, guid, insert_in_content=True, filename=None, prompt=False, **unk_args):