def test_note_deleted(fake_storage):
    test_notes = [
        Note(
            guid="id1",
            title="test",
            content="test",
            notebookGuid="notebook1",
            active=True,
        ),
        Note(
            guid="id2",
            title="test",
            content="test",
            notebookGuid="notebook1",
            active=True,
        ),
    ]

    for note in test_notes:
        fake_storage.notes.add_note(note)

    fake_storage.notes.expunge_notes(["id2"])

    result = list(fake_storage.notes.iter_notes("notebook1"))

    assert len(result) == 1
    assert result[0].guid == "id1"
def test_get_notes_for_sync(fake_storage):
    test_notes = [
        Note(
            guid="id1",
            title="name1",
        ),
        Note(
            guid="id2",
            title="name2",
        ),
        Note(
            guid="id3",
            title="name3",
        ),
    ]

    fake_storage.notes.add_notes_for_sync(test_notes)

    expected = tuple(
        NoteForSync(guid=n.guid, title=n.title, linked_notebook_guid=None)
        for n in test_notes
    )
    result = fake_storage.notes.get_notes_for_sync()

    assert expected == result
def test_trash_notes_count(fake_storage):
    test_notes = [
        Note(
            guid="id1",
            title="test",
            content="test",
            notebookGuid="test",
            active=True,
        ),
        Note(
            guid="id2",
            title="test",
            content="test",
            notebookGuid="test",
            active=False,
        ),
        Note(
            guid="id3",
            title="test",
            content="test",
            notebookGuid="test",
            active=False,
        ),
    ]

    for note in test_notes:
        fake_storage.notes.add_note(note)

    result = fake_storage.notes.get_notes_count(is_active=False)

    assert result == 2
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 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 test_notes_trash(fake_storage):
    test_notes = [
        Note(
            guid="id1",
            title="test",
            content="test",
            notebookGuid="notebook1",
            active=False,
        ),
        Note(
            guid="id2",
            title="test",
            content="test",
            notebookGuid="notebook2",
            active=False,
        ),
        Note(
            guid="id3",
            title="test",
            content="test",
            notebookGuid="notebook1",
            active=True,
        ),
    ]

    expected_notes = [
        Note(
            guid="id1",
            title="test",
            content="test",
            notebookGuid="notebook1",
            active=False,
        ),
        Note(
            guid="id2",
            title="test",
            content="test",
            notebookGuid="notebook2",
            active=False,
        ),
    ]

    for note in test_notes:
        fake_storage.notes.add_note(note)

    result_notes = list(fake_storage.notes.iter_notes_trash())

    assert result_notes == expected_notes
def test_sync_interrupt_download(cli_invoker, mock_evernote_client,
                                 fake_storage, mocker):
    test_notes = [Note(guid=f"id{i}", title="test") for i in range(100)]

    mock_evernote_client.fake_notes.extend(test_notes)

    def interrupter(note):
        if note.guid == "id10":
            raise KeyboardInterrupt

    def fake_slow_get_note(note_guid):
        time.sleep(0.1)
        return Note(
            guid=note_guid,
            title="test",
            content="test",
            notebookGuid="test",
            contentLength=100,
            active=True,
        )

    mock_get_note = mocker.patch(
        "evernote_backup.evernote_client_sync.EvernoteClientSync.get_note")
    mock_get_note.side_effect = fake_slow_get_note

    mock_add_note = mocker.patch(
        "evernote_backup.note_storage.NoteStorage.add_note")
    mock_add_note.side_effect = interrupter

    cli_invoker("sync", "--database", "fake_db")
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(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_sync_exception_while_download_retry_fail(cli_invoker,
                                                  mock_evernote_client,
                                                  fake_storage, mocker):
    test_notes = [Note(guid=f"id{i}", title="test") for i in range(100)]

    mock_evernote_client.fake_notes.extend(test_notes)

    def fake_get_note(note_guid):
        if note_guid == "id10":
            raise struct.error

        return Note(
            guid=note_guid,
            title="test",
            content="test",
            notebookGuid="test",
            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

    with pytest.raises(RuntimeError) as excinfo:
        cli_invoker("sync", "--database", "fake_db")

    assert "Failed to download note" in str(excinfo.value)
Exemple #11
0
def create_note(auth_token,
                note_store,
                note_title,
                note_body,
                note_tags,
                parentNotebook=None):
    body = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
    body += "<!DOCTYPE en-note SYSTEM \"http://xml.evernote.com/pub/enml2.dtd\">"
    body += "<en-note>%s</en-note>" % note_body

    # strip spaces, see http://dev.evernote.com/doc/reference/Types.html#Struct_Note
    note_title = note_title.strip()

    # https://dev.evernote.com/doc/reference/javadoc/constant-values.html#com.evernote.edam.limits.Constants.EDAM_APPLICATIONDATA_VALUE_LEN_MIN
    if len(note_title) > 255:
        note_title = note_title[:255]
    elif not note_title:
        note_title = "无标题文档"

    logger.info(f"title: {note_title}")
    logger.info(f"body: {body}")

    # Create note object
    note = Note()
    note.title = note_title
    note.content = body
    note.tagNames = note_tags

    # parentNotebook is optional; if omitted, default notebook is used
    if parentNotebook and hasattr(parentNotebook, 'guid'):
        note.notebookGuid = parentNotebook.guid

    # Attempt to create note in Evernote account
    note = note_store.createNote(auth_token, note)
    return note
Exemple #12
0
def test_export_yes_trash_single_notes(cli_invoker, fake_storage, tmp_path):
    test_out_path = tmp_path / "test_out"

    fake_storage.notes.add_note(
        Note(
            guid="id1",
            title="title1",
            content="test",
            notebookGuid="nbid1",
            active=False,
        )
    )

    cli_invoker(
        "export",
        "--database",
        "fake_db",
        "--include-trash",
        "--single-notes",
        str(test_out_path),
    )

    book1_path = test_out_path / "Trash" / "title1.enex"

    assert book1_path.is_file()
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 saveToEvernote(history):
    EN_URL = 'https://sandbox.evernote.com'

    dev_token = "S=s1:U=8d5df:E=14a1ce2575a:C=142c5312b5c:P=1cd:A=en-devtoken:V=2:H=c3fba302a245ad5e2aa489bc02b3b873"
    client = EvernoteClient(token=dev_token)
    userStore = client.get_user_store()
    note_store = client.get_note_store()

    note = Note()
    note.title = "chat history"
    note.content = '<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd">'
    content = ''
    for line in history:
        content += "<br>" + line + "</br>"
    note.content += '<en-note>' + content + '</en-note>'
    note = note_store.createNote(note)
    print note.content

    def getUserShardId(authToken, userStore):
        """
	Get the User from userStore and return the user's shard ID
	"""
        try:
            user = userStore.getUser(authToken)
        except (EDAMUserException, EDAMSystemException), e:
            print "Exception while getting user's shardID:"
            print type(e), e
            return None

        if hasattr(user, 'shardId'):
            return user.shardId
        return None
def make_note(auth_token,
              note_store,
              title,
              body,
              date,
              tag,
              parent_notebook=None):

    # Create note object
    note = Note()
    note.title = title
    note.tagGuids = [tag]
    note.created = date
    note.updated = date
    note.content = ''.join([
        '<?xml version="1.0" encoding="UTF-8"?>',
        '<!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd">',
        '<en-note>{}</en-note>'.format(body),
    ])

    # parent_notebook is optional; if omitted, default notebook is used
    if parent_notebook:
        note.notebookGuid = parent_notebook

    # Attempt to create note in Evernote account
    try:
        return note_store.createNote(note)
    except Exception as e:
        # Something was wrong with the note data
        # See EDAMErrorCode enumeration for error code explanation
        # http://dev.evernote.com/documentation/reference/Errors.html#Enum_EDAMErrorCode
        print('whoa', e)
        return None
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_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_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()
Exemple #20
0
def test_formatter_empty_note():
    formatter = NoteFormatter()

    test_empty_note = Note()
    expected_empty_note = "  <note>\n  </note>\n"

    formatted_note = formatter.format_note(test_empty_note)

    assert formatted_note == expected_empty_note
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 fake_slow_get_note(note_guid):
     time.sleep(0.1)
     return Note(
         guid=note_guid,
         title="test",
         content="test",
         notebookGuid="test",
         contentLength=100,
         active=True,
     )
Exemple #23
0
def share_evernote(user, article):
    client = get_evernote_client(user['extras']['evernote'])
    note_store = client.get_note_store()
    note = Note()
    note.title = article.title
    note.content = '<?xml version="1.0" encoding="UTF-8"?>'
    note.content += '<!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd">'
    note.content += '<en-note>{0}<br /><a href="{1}">[Article Link]</a></en-note>'.format(
        article.excerpt, article.url)
    note_store.createNote(note)
    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('&', '&amp;')
        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_notes_order(fake_storage):
    test_notes = [
        Note(
            guid="id5",
            title="test5",
            content="test",
            notebookGuid="notebook1",
            active=True,
        ),
        Note(
            guid="id4",
            title="test4",
            content="test",
            notebookGuid="notebook1",
            active=True,
        ),
        Note(
            guid="id2",
            title="test1",
            content="test",
            notebookGuid="notebook1",
            active=True,
        ),
        Note(
            guid="id1",
            title="test2",
            content="test",
            notebookGuid="notebook1",
            active=True,
        ),
    ]

    expected_notes_titles_order = ["test1", "test2", "test4", "test5"]

    for note in test_notes:
        fake_storage.notes.add_note(note)

    result_notes_titles_order = list(
        n.title for n in fake_storage.notes.iter_notes("notebook1")
    )

    assert result_notes_titles_order == expected_notes_titles_order
 def store_note(self, note_title, note_content):
     notebook_guid = self.get_notebook_guid()
     if notebook_guid is None:
         notebook_guid = self.create_default_notebook()
     note = Note()
     note.title = note_title
     note.content = HackzurichEvernoteClient.NOTE_BOILERPLATE.format(
         note_content)
     note.notebookGuid = notebook_guid
     self._note_store.createNote(note)
     return note.guid
Exemple #27
0
 def notes_local(self):
     """Send local notes changes to server"""
     for note in self.sq(models.Note).filter(
             and_(
                 models.Note.action != ACTION_NONE,
                 models.Note.action != ACTION_NOEXSIST,
                 models.Note.action != ACTION_CONFLICT,
             )):
         self.app.log('Note %s local' % note.title)
         content = (u"""
                 <!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd">
                 <en-note>%s</en-note>
             """ % sanitize(html=note.content[:EDAM_NOTE_CONTENT_LEN_MAX])
                    ).strip().encode('utf8')
         soup = BeautifulStoneSoup(content,
                                   selfClosingTags=[
                                       'img',
                                       'en-todo',
                                       'en-media',
                                       'br',
                                       'hr',
                                   ])
         kwargs = dict(
             title=note.title[:EDAM_NOTE_TITLE_LEN_MAX].strip().encode(
                 'utf8'),
             content=soup.prettify(),
             tagGuids=map(
                 lambda tag: tag.guid,
                 note.tags,
             ),
         )
         if note.notebook:
             kwargs['notebookGuid'] = note.notebook.guid
         if note.guid:
             kwargs['guid'] = note.guid
         nt = Note(**kwargs)
         try:
             next_action = ACTION_NONE
             if note.action == ACTION_CHANGE:
                 nt.resources = self._resources_for_note(note)
                 nt = self.note_store.updateNote(self.auth_token, nt)
             elif note.action == ACTION_CREATE:
                 nt.resources = self._resources_for_note(note)
                 nt = self.note_store.createNote(self.auth_token, nt)
                 note.guid = nt.guid
             elif note.action == ACTION_DELETE:
                 self.note_store.deleteNote(self.auth_token, nt.guid)
                 self.session.delete(note)
         except EDAMUserException as e:
             next_action = ACTION_NONE
             self.app.log('Note %s failed' % note.title)
             self.app.log(e)
         note.action = next_action
     self.session.commit()
Exemple #28
0
def init_note(guid, content):

    # Initializing the note object
    note = Note()
    note.content = content
    note.guid = guid

    # Getting note title
    soup = BeautifulSoup(content, "html.parser")
    note.title = soup.title.text

    # Initializing variables
    resources = []
    resource = None
    data = None
    binaryData = None
    hash = None

    # Getting note resources
    path = safeglobals.path_note % (guid, "")
    for filename in os.listdir(path):
        if "content.json" not in filename:

            # Reading binary data
            with open(os.path.join(path, filename), "rb") as f:
                binaryData = f.read()

            # Calculating hash
            md5 = hashlib.md5()
            md5.update(binaryData)
            hash = md5.digest()

            # Creating data
            data = Data()
            data.size = len(binaryData)
            data.bodyHash = hash
            data.body = binaryData

            # Create a new resource
            resource = Resource()
            resource.mime = getMime(filename)
            resource.data = data

            # Creating attributes
            attributes = ResourceAttributes()
            attributes.fileName = filename

            # Adding the resource to resource collection
            resource.attributes = attributes
            resources.append(resource)

    # Adding resources to the specified note
    note.resources = resources
    return note
    def fake_get_note(note_guid):
        if note_guid == "id10":
            raise struct.error

        return Note(
            guid=note_guid,
            title="test",
            content="test",
            notebookGuid="test",
            contentLength=100,
            active=True,
        )
    def fake_get_note(note_guid):
        if note_guid == "id10":
            raise RuntimeError("Test error")

        return Note(
            guid=note_guid,
            title="test",
            content="test",
            notebookGuid="test",
            contentLength=100,
            active=True,
        )