def test_notebooks(fake_storage): test_notebooks = [ Notebook( guid="id1", name="name1", stack="stack1", ), Notebook( guid="id2", name="name2", stack="stack2", ), ] expected_notebooks = [ Notebook( guid="id1", name="name1", stack="stack1", ), Notebook( guid="id2", name="name2", stack="stack2", ), ] fake_storage.notebooks.add_notebooks(test_notebooks) # Output without updated timestamp result_notebooks = list(fake_storage.notebooks.iter_notebooks()) assert result_notebooks == expected_notebooks
def test_sync_expunge_notebooks(cli_invoker, mock_evernote_client, fake_storage): test_notebooks = [ Notebook( guid="id1", name="name1", stack="stack1", ), Notebook( guid="id2", name="name1", stack="stack1", ), Notebook( guid="id3", name="name1", stack="stack1", ), ] fake_storage.notebooks.add_notebooks(test_notebooks) fake_storage.config.set_config_value("USN", "1") mock_evernote_client.fake_expunged_notebooks = ["id1", "id3"] cli_invoker("sync", "--database", "fake_db") result_notebooks = list(fake_storage.notebooks.iter_notebooks()) assert len(result_notebooks) == 1 assert result_notebooks[0].guid == "id2"
def test_linked_notebook(fake_storage): test_notebooks = [ Notebook( guid="id1", name="name1", stack="stack1", ), Notebook( guid="id2", name="name2", stack="stack2", ), ] test_l_notebook = LinkedNotebook(guid="id3") expected_notebook = test_notebooks[0] fake_storage.notebooks.add_notebooks(test_notebooks) fake_storage.notebooks.add_linked_notebook(test_l_notebook, test_notebooks[0]) result_notebook = fake_storage.notebooks.get_notebook_by_linked_guid( test_l_notebook.guid ) assert result_notebook == expected_notebook
def test_export_single_notes_over_existing_overwrite(cli_invoker, fake_storage, tmp_path): test_out_path = tmp_path / "test_out" test_notebooks = [ Notebook(guid="nbid1", name="name1", stack="stack1"), Notebook(guid="nbid2", name="name2", stack=None), ] test_notes = [ Note( guid="id1", title="title1", content="test", notebookGuid="nbid1", active=True, ), Note( guid="id2", title="title2", content="test", notebookGuid="nbid2", active=True, ), ] fake_storage.notebooks.add_notebooks(test_notebooks) for note in test_notes: fake_storage.notes.add_note(note) book1_existing_path = test_out_path / "stack1" / "name1" / "title1.enex" book2_existing_path = test_out_path / "name2" / "title2.enex" book1_existing_path.parent.mkdir(parents=True, exist_ok=True) book2_existing_path.parent.mkdir(parents=True, exist_ok=True) book1_existing_path.touch() book2_existing_path.touch() cli_invoker( "export", "--database", "fake_db", "--single-notes", "--overwrite", str(test_out_path), ) assert book1_existing_path.stat().st_size > 0 assert book2_existing_path.stat().st_size > 0
def notebooks_local(self): """Send local notebooks changes to server""" for notebook in self.sq(models.Notebook).filter( models.Notebook.action != ACTION_NONE, ): self.app.log('Notebook %s local' % notebook.name) kwargs = dict( name=notebook.name[:EDAM_NOTEBOOK_NAME_LEN_MAX].strip().encode( 'utf8'), defaultNotebook=notebook.default, ) if notebook.guid: kwargs['guid'] = notebook.guid nb = Notebook(**kwargs) if notebook.action == ACTION_CHANGE: while True: try: nb = self.note_store.updateNotebook( self.auth_token, nb, ) break except EDAMUserException, e: notebook.name = notebook.name + '*' # shit, but work print e elif notebook.action == ACTION_CREATE: nb = self.note_store.createNotebook( self.auth_token, nb, ) notebook.guid = nb.guid
def test_sync_custom_max_chunk_results(cli_invoker, mock_evernote_client, fake_storage): mock_evernote_client.fake_notebooks.append( Notebook( guid="nbid1", name="name1", stack="stack1", serviceUpdated=1000, ), ) test_note = Note( guid="id1", title="title1", content="body1", notebookGuid="nbid1", contentLength=100, active=True, ) mock_evernote_client.fake_notes.append(test_note) test_max_chunk_results = 100 cli_invoker("sync", "--database", "fake_db", "--max-chunk-results", test_max_chunk_results) result_notes = list(fake_storage.notes.iter_notes("nbid1")) assert result_notes == [test_note] assert mock_evernote_client.last_maxEntries == test_max_chunk_results
def test_sync_add_note(cli_invoker, mock_evernote_client, fake_storage): mock_evernote_client.fake_notebooks.append( Notebook( guid="nbid1", name="name1", stack="stack1", serviceUpdated=1000, ), ) test_note = Note( guid="id1", title="title1", content="body1", notebookGuid="nbid1", active=True, contentLength=100, ) mock_evernote_client.fake_notes.append(test_note) cli_invoker("sync", "--database", "fake_db") result_notes = list(fake_storage.notes.iter_notes("nbid1")) assert result_notes == [test_note]
def test_export_no_export_date(cli_invoker, fake_storage, tmp_path): test_out_path = tmp_path / "test_out" test_notebooks = [ Notebook(guid="nbid1", name="name1", stack=None), ] fake_storage.notebooks.add_notebooks(test_notebooks) fake_storage.notes.add_note( Note( guid="id1", title="title1", content="test", notebookGuid="nbid1", active=True, )) cli_invoker( "export", "--database", "fake_db", "--no-export-date", str(test_out_path), ) book1_path = test_out_path / "name1.enex" with open(book1_path, "r") as f: book1_xml = f.read() assert "export-date" not in book1_xml
def test_sync_massive_note_count(cli_invoker, mock_evernote_client, fake_storage, monkeypatch): mock_evernote_client.fake_notebooks.append( Notebook( guid="nbid1", name="name1", stack="stack1", serviceUpdated=1000, ), ) for i in range(10): test_note = Note( guid=f"id{i}", title=f"title{i}", content="body1", notebookGuid="nbid1", contentLength=100, active=True, ) mock_evernote_client.fake_notes.append(test_note) monkeypatch.setattr(note_synchronizer, "THREAD_CHUNK_SIZE", 2) cli_invoker("sync", "--database", "fake_db") result_notes = sorted(fake_storage.notes.iter_notes("nbid1"), key=lambda x: int(x.guid[2:])) assert result_notes == mock_evernote_client.fake_notes
def test_sync_add_linked_notebook_note_error_no_access(cli_invoker, mock_evernote_client, fake_storage): mock_evernote_client.fake_l_notebooks.append( Notebook( guid="nbid1", name="name1", ), ) mock_evernote_client.fake_l_notes.append( Note( guid="id1", title="title1", content="body1", notebookGuid="nbid1", contentLength=100, active=True, )) mock_evernote_client.fake_linked_notebooks.append( LinkedNotebook(guid="id3")) mock_evernote_client.fake_linked_notebook_auth_token = ( "S=200:U=ff:E=fff:C=ff:P=1:A=test222:V=2:H=ff") mock_evernote_client.fake_auth_linked_notebook_error = True cli_invoker("sync", "--database", "fake_db") result_notebooks = list(fake_storage.notebooks.iter_notebooks()) result_notes = list(fake_storage.notes.iter_notes("nbid1")) assert result_notebooks == [] assert result_notes == []
def test_sync_add_note_with_res(cli_invoker, mock_evernote_client, fake_storage): mock_evernote_client.fake_notebooks.append( Notebook( guid="nbid1", name="name1", stack="stack1", serviceUpdated=1000, ), ) test_note = Note( guid="id1", title="title1", content="body1", notebookGuid="nbid1", active=True, contentLength=100, resources=[ Resource( guid="rid2", noteGuid="id1", data=Data(bodyHash=md5(b"000").digest(), size=3, body=b"000"), ) ], ) mock_evernote_client.fake_notes.append(test_note) cli_invoker("sync", "--database", "fake_db") result_notes = list(fake_storage.notes.iter_notes("nbid1")) assert result_notes == [test_note]
def test_export_over_existing(cli_invoker, fake_storage, tmp_path): test_out_path = tmp_path / "test_out" test_notebooks = [ Notebook(guid="nbid1", name="name1", stack="stack1"), Notebook(guid="nbid2", name="name2", stack=None), Notebook(guid="nbid3", name="name3", stack=None), ] test_notes = [ Note( guid="id1", title="title1", content="test", notebookGuid="nbid1", active=True, ), Note( guid="id2", title="test", content="test", notebookGuid="nbid2", active=True, ), ] fake_storage.notebooks.add_notebooks(test_notebooks) for note in test_notes: fake_storage.notes.add_note(note) book1_existing_path = test_out_path / "stack1" / "name1.enex" book2_existing_path = test_out_path / "name2.enex" book1_existing_path.parent.mkdir(parents=True, exist_ok=True) book2_existing_path.parent.mkdir(parents=True, exist_ok=True) book1_existing_path.touch() book2_existing_path.touch() book1_expected_path = test_out_path / "stack1" / "name1 (1).enex" book2_expected_path = test_out_path / "name2 (1).enex" cli_invoker("export", "--database", "fake_db", str(test_out_path)) assert book1_expected_path.is_file() assert book2_expected_path.is_file()
def iter_notebooks(self) -> Iterator[Notebook]: with self.db as con: cur = con.execute("select guid, name, stack from notebooks", ) yield from (Notebook( guid=row["guid"], name=row["name"], stack=row["stack"], ) for row in cur)
def __init__(self, token, **kwargs): fake_notes = NotesMetadataList(startIndex=0, totalNotes=0, notes=[]) fake_notebooks = [] note_store = Mock() note_store.listNotebooks.return_value = kwargs.get('fake_notebooks', fake_notebooks) note_store.findNotesMetadata.return_value = kwargs.get('fake_notes', fake_notes) note_store.getNote.return_value = kwargs.get('fake_get_note', None) note_store.createNotebook.return_value = Notebook(guid='notebook-guid') self.note_store = note_store super(MockMininote, self).__init__(token)
def get(self, file_id): client = self.get_authorized_client() if not client: return self.redirect('/auth-evernote?next={0}'.format(self.request.path)) try: file = self.get_file(file_id) except webapp2.HTTPException as http_ex: if http_ex.code == 401: return self.redirect('/auth?next={0}'.format(self.request.path)) base_url = self.request.host_url + '/edit/{0}'.format(file['id']) extension_loaded = bool(int(self.request.get('extensionLoaded', 1))) # Look for the VideoNot.es Notebook notestore = client.get_note_store() notesbooks = notestore.listNotebooks() notebook = None for a_notesbook in notesbooks: if a_notesbook.name == 'VideoNot.es': notebook = a_notesbook break if not notebook: notebook = Notebook() notebook.name = 'VideoNot.es' notebook = notestore.createNotebook(notebook) # Formatting the note in ENML content_enml = FileUtils.to_ENML(file, base_url) content_enml.append('<br></br><br></br>') content_enml.append('<a href="{0}">View in VideoNot.es</a>'.format(base_url)) if not extension_loaded: content_enml.append('<br/>') content_enml.append('(Tip: you can add snapshots of the video to your export by installing our <a href="https://chrome.google.com/webstore/detail/kmbcnighpdagelfjmlbakfnciogcelgi">Chrome Extension</a>)') # Saving the note in Evernote note = Note() note.title = file['title'] note_content = ''.join(content_enml).encode('utf-8') note.content = '<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd"><en-note>{0}</en-note>'.format(note_content) note.content = note.content.replace('&', '&') if notebook: note.notebookGuid = notebook.guid note = notestore.createNote(note) logging.debug('VideoNot.es %s exported to Evernote: %s', file_id, note_content) logging.info('VideoNot.es %s exported to Evernote with id: %s', file_id, note.guid) # Returning to the new note in Evernote user_store = client.get_user_store() notestore_url = '/'.join(user_store.getNoteStoreUrl().split('/')[0:5]) return self.redirect(notestore_url + '/view/notebook/{0}'.format(note.guid))
def test_linked_notebook_deleted(fake_storage): test_notebook = Notebook(guid="id1", name="name1", stack="stack1") test_l_notebook = LinkedNotebook(guid="id3") fake_storage.notebooks.add_notebooks([test_notebook]) fake_storage.notebooks.add_linked_notebook(test_l_notebook, test_notebook) fake_storage.notebooks.expunge_linked_notebooks([test_l_notebook.guid]) with pytest.raises(ValueError): fake_storage.notebooks.get_notebook_by_linked_guid(test_l_notebook.guid)
def _get_create_notebook(self): """ Get or create the Evernote notebook. :returns: Notebook guid """ for notebook in self._note_store().listNotebooks(): if notebook.name == EVERNOTE_NOTEBOOK: return notebook.guid return self._note_store() \ .createNotebook(Notebook(name=EVERNOTE_NOTEBOOK)) \ .guid
def test_linked_notebook_asn(fake_storage): test_notebook = Notebook(guid="id1", name="name1", stack="stack1") test_l_notebook = LinkedNotebook(guid="id3") fake_storage.notebooks.add_notebooks([test_notebook]) fake_storage.notebooks.add_linked_notebook(test_l_notebook, test_notebook) fake_storage.notebooks.set_linked_notebook_usn(test_l_notebook.guid, 100) result = fake_storage.notebooks.get_linked_notebook_usn(test_l_notebook.guid) assert result == 100
def notebooks_local(self): """Send local notebooks changes to server""" for notebook in self.sq(models.Notebook).filter( models.Notebook.action != ACTION_NONE, ): self.app.log('Notebook %s local' % notebook.name) kwargs = dict( name=notebook.name[:EDAM_NOTEBOOK_NAME_LEN_MAX].strip().encode( 'utf8'), defaultNotebook=notebook.default, ) if notebook.stack: kwargs[ 'stack'] = notebook.stack[: EDAM_NOTEBOOK_STACK_LEN_MAX].strip( ).encode('utf8') if not regex.search(EDAM_NOTEBOOK_NAME_REGEX, notebook.name): self.app.log('notebook %s skipped' % notebook.name) notebook.action = ACTION_NONE continue # just ignore it if notebook.guid: kwargs['guid'] = notebook.guid nb = Notebook(**kwargs) if notebook.action == ACTION_CHANGE: try: nb = self.note_store.updateNotebook( self.auth_token, nb, ) notebook.action = ACTION_NONE except EDAMUserException: notebook.action = ACTION_DUPLICATE self.app.log('Duplicate %s' % nb.name) elif notebook.action == ACTION_CREATE: try: nb = self.note_store.createNotebook( self.auth_token, nb, ) notebook.guid = nb.guid notebook.action = ACTION_NONE except EDAMUserException: notebook.action = ACTION_DUPLICATE self.app.log('Duplicate %s' % nb.name) elif notebook.action == ACTION_DELETE and False: # not allowed for app now try: self.note_store.expungeNotebook( self.auth_token, notebook.guid, ) self.session.delete(notebook) except EDAMUserException, e: self.app.log(e)
def test_notebook_deleted(fake_storage): test_notebooks = [ Notebook( guid="id1", name="name1", stack="stack1", ), Notebook( guid="id2", name="name2", stack="stack2", ), ] fake_storage.notebooks.add_notebooks(test_notebooks) fake_storage.notebooks.expunge_notebooks(["id2"]) result = list(fake_storage.notebooks.iter_notebooks()) assert len(result) == 1 assert result[0].guid == "id1"
def test_sync_add_notebook(cli_invoker, mock_evernote_client, fake_storage): test_notebooks = [Notebook( guid="id1", name="name1", stack="stack1", )] mock_evernote_client.fake_notebooks = test_notebooks cli_invoker("sync", "--database", "fake_db") result_notebooks = list(fake_storage.notebooks.iter_notebooks()) assert result_notebooks == test_notebooks
def test_notebook_note_count(fake_storage): expected_notebooks = [ Notebook( guid="notebook1", name="name1", stack="stack1", ), Notebook( guid="notebook2", name="name2", stack="stack2", ), ] test_notes = [ Note( guid="id1", title="test", content="test", notebookGuid="notebook1", active=True, ), Note( guid="id2", title="test", content="test", notebookGuid="notebook1", active=False, ), ] for note in test_notes: fake_storage.notes.add_note(note) fake_storage.notebooks.add_notebooks(expected_notebooks) result = fake_storage.notebooks.get_notebook_notes_count("notebook1") assert result == 1
def test_export(cli_invoker, fake_storage, tmp_path): test_out_path = tmp_path / "test_out" test_notebooks = [ Notebook(guid="nbid1", name="name1", stack="stack1"), Notebook(guid="nbid2", name="name2", stack=None), Notebook(guid="nbid3", name="name3", stack=None), ] test_notes = [ Note( guid="id1", title="title1", content="test", notebookGuid="nbid1", active=True, ), Note( guid="id2", title="test", content="test", notebookGuid="nbid2", active=True, ), ] fake_storage.notebooks.add_notebooks(test_notebooks) for note in test_notes: fake_storage.notes.add_note(note) cli_invoker("export", "--database", "fake_db", str(test_out_path)) book1_path = test_out_path / "stack1" / "name1.enex" book2_path = test_out_path / "name2.enex" assert book1_path.is_file() assert book2_path.is_file()
def test_sync_exception_while_download_retry(cli_invoker, mock_evernote_client, fake_storage, mocker): mock_evernote_client.fake_notebooks.append( Notebook( guid="nbid1", name="name1", stack="stack1", serviceUpdated=1000, ), ) test_notes = [ Note( guid=f"id{i}", title="test", content="test", notebookGuid="nbid1", contentLength=100, active=True, ) for i in range(10) ] mock_evernote_client.fake_notes.extend(test_notes) retry_count = 3 def fake_get_note(note_guid): nonlocal retry_count if note_guid == "id3" and retry_count > 0: retry_count -= 1 raise struct.error return Note( guid=note_guid, title="test", content="test", notebookGuid="nbid1", contentLength=100, active=True, ) mock_get_note = mocker.patch( "evernote_backup.evernote_client_sync.EvernoteClientSync.get_note") mock_get_note.side_effect = fake_get_note cli_invoker("sync", "--database", "fake_db") result_notes = list(fake_storage.notes.iter_notes("nbid1")) assert set(result_notes) == set(test_notes)
def test_sync_add_linked_notebook_note_with_tag(cli_invoker, mock_evernote_client, fake_storage): mock_evernote_client.fake_l_notebooks.append( Notebook( guid="nbid1", name="name1", ), ) mock_evernote_client.fake_l_tags = [ Tag(guid="tid1", name="tag1"), Tag(guid="tid2", name="tag2"), ] mock_evernote_client.fake_l_notes.append( Note( guid="id1", title="title1", content="body1", notebookGuid="nbid1", active=True, contentLength=100, tagGuids=["tid1", "tid2"], )) expected_notes = [ Note( guid="id1", title="title1", content="body1", notebookGuid="nbid1", active=True, contentLength=100, tagGuids=["tid1", "tid2"], tagNames=["tag1", "tag2"], ) ] mock_evernote_client.fake_linked_notebooks.append( LinkedNotebook(guid="id3", shardId="s100")) mock_evernote_client.fake_linked_notebook_auth_token = ( "S=200:U=ff:E=fff:C=ff:P=1:A=test222:V=2:H=ff") cli_invoker("sync", "--database", "fake_db") result_notes = list(fake_storage.notes.iter_notes("nbid1")) assert result_notes == expected_notes
def tset_notebook(store, name): """Return notebook with specific name. Create a new notebook if there isn't an existing one. """ notebooks = store.listNotebooks() notebook = [nb for nb in notebooks if nb.name == name] if notebook: log('Found notebook {}'.format(name)) return notebook[0] else: notebook = Notebook() notebook.name = name notebook.defaultNotebook = False log('Create new notebook {}'.format(name)) return store.createNotebook(dev_token, notebook)
def test_sync_nothing_to_sync(cli_invoker, mock_evernote_client, fake_storage): mock_evernote_client.fake_notebooks.append( Notebook( guid="id1", name="name1", stack="stack1", ), ) fake_storage.config.set_config_value("USN", mock_evernote_client.fake_usn) cli_invoker("sync", "--database", "fake_db") result_notebooks = list(fake_storage.notebooks.iter_notebooks()) assert not result_notebooks
def test_sync_add_linked_notebook_stack(cli_invoker, mock_evernote_client, fake_storage): mock_evernote_client.fake_l_notebooks.append( Notebook( guid="nbid1", name="name1", ), ) mock_evernote_client.fake_linked_notebooks.append( LinkedNotebook(guid="id3", stack="test_stack")) expected_notebooks = [ Notebook( guid="nbid1", name="name1", stack="test_stack", ) ] cli_invoker("sync", "--database", "fake_db") result_notebooks = list(fake_storage.notebooks.iter_notebooks()) assert result_notebooks == expected_notebooks
def test_sync_add_note_with_tags(cli_invoker, mock_evernote_client, fake_storage): mock_evernote_client.fake_tags = [ Tag(guid="tid1", name="tag1"), Tag(guid="tid2", name="tag2"), ] mock_evernote_client.fake_notebooks.append( Notebook( guid="nbid1", name="name1", stack="stack1", serviceUpdated=1000, ), ) mock_evernote_client.fake_notes.append( Note( guid="id1", title="title1", content="body1", notebookGuid="nbid1", active=True, contentLength=100, tagGuids=["tid1", "tid2"], )) expected_notes = [ Note( guid="id1", title="title1", content="body1", notebookGuid="nbid1", active=True, contentLength=100, tagGuids=["tid1", "tid2"], tagNames=["tag1", "tag2"], ) ] cli_invoker("sync", "--database", "fake_db") result_notes = list(fake_storage.notes.iter_notes("nbid1")) assert result_notes == expected_notes
def notify(title, message, access_token=None, notebook='ntfy-notifications', sandbox=False, china=False, **_): try: client = EvernoteClient( consumer_key=CONSUMER_KEY, consumer_secret=CONSUMER_SECRET, token=access_token, sandbox=sandbox, china=china ) if not client.token: login(client=client) if not client.token: print(f'Skiped with not login.') return 1 noteStore = client.get_note_store() nbs = noteStore.listNotebooks() nb = ([x for x in nbs if x.name == notebook] + [None])[0] if nb is None: nb = Notebook(name=notebook) nb = noteStore.createNotebook(nb) note = Note(notebookGuid=nb.guid) note.title = str(title) note.content = '<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd">' note.content += f'<en-note>{escape(message)}</en-note>' noteStore = client.get_note_store() note = noteStore.createNote(note) except EDAMUserException as ue: if ue.errorCode == EDAMErrorCode.RATE_LIMIT_REACHED: print(f'Rate limit reached, Retry your request in {ue.rateLimitDuration} seconds') return 1 else: raise