imports needed

What library am I using?

http://dev.evernote.com/

When I'm ready I would hit a Get API key button and fill out the form: https://www.evernote.com/shard/s1/sh/e03e0393-b2cb-4a54-94d1-60e65f482ad3/bb93b060e287d4d979fef70d7b997df9

Docs:

In getting started, you can take one or both of the following approaches:

  • get a key set up for the sandbox
  • set up a dev key to work with your own account and not worry about Oauth initially.

you can have a dev token for both the sandbox and for production to access production accounts:

EvernoteWebUtil is my wrapper for ...


In [ ]:
import settings
from evernote.api.client import EvernoteClient

dev_token = settings.authToken

client = EvernoteClient(token=dev_token, sandbox=False)

userStore = client.get_user_store()
user = userStore.getUser()
print user.username

In [ ]:
import EvernoteWebUtil as ewu
ewu.init(settings.authToken)

ewu.user.username

noteStore

getting notebook by name


In [ ]:
# getting notes for a given notebook

import datetime

from itertools import islice
notes = islice(ewu.notes_metadata(includeTitle=True, 
                                  includeUpdated=True,
                                  includeUpdateSequenceNum=True,
                                  notebookGuid=ewu.notebook(name=':CORE').guid), None)

for note in notes:
    print note.title, note.updateSequenceNum, datetime.datetime.fromtimestamp(note.updated/1000.)

In [ ]:
# let's read my __MASTER note__
# is it possible to search notes by title?

[(n.guid, n.title) for n in ewu.notes(title=".__MASTER note__")]

In [ ]:
import settings
from evernote.api.client import EvernoteClient

dev_token = settings.authToken

client = EvernoteClient(token=dev_token, sandbox=False)

userStore = client.get_user_store()
user = userStore.getUser()

noteStore = client.get_note_store()

print user.username

In [ ]:
userStore.getUser()
noteStore.getNoteContent('ecc59d05-c010-4b3b-a04b-7d4eeb7e8505')

my .__MASTER note__ is actually pretty complex....so parsing it and adding to it will take some effort. But let's give it a try.

Working with Note Contents

Things to figure out:

  • XML parsing
  • XML creation
  • XML validation via schema

In [ ]:
import lxml

Getting tags by name


In [ ]:
ewu.tag('#1-Now')

In [ ]:
sorted(ewu.tag_counts_by_name().items(), key=lambda x: -x[1])[:10]

In [ ]:
tags = ewu.noteStore.listTags()
tags_by_name = dict([(tag.name, tag) for tag in tags])
tag_counts_by_name = ewu.tag_counts_by_name()
tags_by_guid = ewu.tags_by_guid()

In [ ]:
# figure out which tags have no notes attached and possibly delete them -- say if they don't have children tags
# oh -- don't delete them willy nilly -- some have organizational purposes

set(tags_by_name) - set(tag_counts_by_name)

In [ ]:
# calculated tag_children -- tags that have children

from collections import defaultdict

tag_children = defaultdict(list)
for tag in tags:
    if tag.parentGuid is not None:
        tag_children[tag.parentGuid].append(tag)

In [ ]:
[tags_by_guid[guid].name for guid in tag_children.keys()]

In [ ]:
for (guid, children) in tag_children.items():
    print tags_by_guid[guid].name
    for child in children:
        print "\t", child.name

things to do with tags

  • find all notes for a given tag
  • get tag guid, name, count, parent / check for existence
  • create new tag
  • delete tag
  • move tag to new parent
  • expunge tags -- disconnect tags from notes
  • can we get history of a tag: when created?
  • dealing with deleted tags
  • find "related" tags -- in the Evernote client, when I click on a specific tag, it seems like I see the highlighting of other, possibly related, tags -- http://dev.evernote.com/documentation/reference/NoteStore.html#Fn_NoteStore_findRelated ?

I will also want to locate notes that have a certain tag or set of tags and are in a certain notebook.


In [ ]:
# find all notes for a given tag

[n.title for n in ewu.notes_metadata(includeTitle=True, tagGuids=[tags_by_name['#1-Now'].guid])]

In [ ]:
ewu.notebook(name='Action Pending').guid

In [ ]:
[n.title for n in ewu.notes_metadata(includeTitle=True, 
                         notebookGuid=ewu.notebook(name='Action Pending').guid, 
                         tagGuids=[tags_by_name['#1-Now'].guid])]

In [ ]:
# with a GUID, you can get the current state of a tag
# http://dev.evernote.com/documentation/reference/NoteStore.html#Fn_NoteStore_getTag
# not super useful for me since I'm already pulling a list of all tags in order to map names to guids

ewu.noteStore.getTag(ewu.tag(name='#1-Now').guid)

In [ ]:
# create a tag
# http://dev.evernote.com/documentation/reference/NoteStore.html#Fn_NoteStore_createTag
# must pass name; optional to pass 

from evernote.edam.type.ttypes import Tag

ewu.noteStore.createTag(Tag(name="happy happy2!", parentGuid=None))

In [ ]:
ewu.tag(name="happy happy2!", refresh=True)

In [ ]:
# expunge tag
# http://dev.evernote.com/documentation/reference/NoteStore.html#Fn_NoteStore_expungeTag

ewu.noteStore.expungeTag(ewu.tag("happy happy2!").guid)

In [ ]:
# find all notes for a given tag and notebook

action_now_notes = list(ewu.notes_metadata(includeTitle=True, 
          notebookGuid=ewu.notebook(name='Action Pending').guid, 
          tagGuids=[tags_by_name['#1-Now'].guid]))

[(n.guid, n.title) for n in action_now_notes ]

In [ ]:
# get all tags for a given note

import datetime

from itertools import islice
notes = list(islice(ewu.notes_metadata(includeTitle=True, 
                                  includeUpdated=True,
                                  includeUpdateSequenceNum=True,
                                  notebookGuid=ewu.notebook(name=':PROJECTS').guid), None))

plus_tags_set = set()

for note in notes:
    tags = ewu.noteStore.getNoteTagNames(note.guid)
    plus_tags = [tag for tag in tags if tag.startswith("+")]
    
    plus_tags_set.update(plus_tags)
    print note.title, note.updateSequenceNum, datetime.datetime.fromtimestamp(note.updated/1000.),  \
         len(plus_tags) == 1

synchronization state


In [ ]:
syncstate = ewu.noteStore.getSyncState()
syncstate

In [ ]:
syncstate.fullSyncBefore, syncstate.updateCount

In [ ]:
import datetime
datetime.datetime.fromtimestamp(syncstate.fullSyncBefore/1000.)

list notebooks and note counts


In [ ]:
ewu.notebookcounts()

compute distribution of note sizes


In [ ]:
k = list(ewu.sizes_of_notes())
print len(k)

In [ ]:
plt.plot(k)

In [ ]:
sort(k)

In [ ]:
plt.plot(sort(k))

In [ ]:
plt.plot([log(i) for i in sort(k)])

In [ ]:
"""
Make a histogram of normally distributed random numbers and plot the
analytic PDF over it
"""
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.mlab as mlab

mu, sigma = 100, 15
x = mu + sigma * np.random.randn(10000)

fig = plt.figure()
ax = fig.add_subplot(111)

# the histogram of the data
n, bins, patches = ax.hist(x, 50, normed=1, facecolor='green', alpha=0.75)

# hist uses np.histogram under the hood to create 'n' and 'bins'.
# np.histogram returns the bin edges, so there will be 50 probability
# density values in n, 51 bin edges in bins and 50 patches.  To get
# everything lined up, we'll compute the bin centers
bincenters = 0.5*(bins[1:]+bins[:-1])
# add a 'best fit' line for the normal PDF
y = mlab.normpdf( bincenters, mu, sigma)
l = ax.plot(bincenters, y, 'r--', linewidth=1)

ax.set_xlabel('Smarts')
ax.set_ylabel('Probability')
#ax.set_title(r'$\mathrm{Histogram\ of\ IQ:}\ \mu=100,\ \sigma=15$')
ax.set_xlim(40, 160)
ax.set_ylim(0, 0.03)
ax.grid(True)

plt.show()

In [ ]:
plt.hist(k)

In [ ]:
plt.hist([log10(i) for i in k], 50)

In [ ]:
# calculate Notebook name -> note count

nb_guid_dict = dict([(nb.guid, nb) for nb in ewu.all_notebooks()])
nb_name_dict = dict([(nb.name, nb) for nb in ewu.all_notebooks()])

In [ ]:
ewu.notes_metadata(includeTitle=True)

In [ ]:
import itertools

In [ ]:
g = itertools.islice(ewu.notes_metadata(includeTitle=True, includeUpdateSequenceNum=True, notebookGuid=nb_name_dict["Action Pending"].guid), 10)

In [ ]:
list(g)

In [ ]:
len(_)

In [ ]:
# grab content of a specific note

# http://dev.evernote.com/documentation/reference/NoteStore.html#Fn_NoteStore_getNote
# params: guid, withContent, withResourcesData, withResourcesRecognition, withResourcesAlternateData

note = ewu.noteStore.getNote('a49d531e-f3f8-4e72-9523-e5a558f11d87', True, False, False, False)



note_content = ewu.noteStore.getNoteContent('a49d531e-f3f8-4e72-9523-e5a558f11d87')

note_content

creating a new note with content and tag

  • Note type
  • noteStore.createNote
  • nice to have convenience of not having to calculate tag guids

In [ ]:
import EvernoteWebUtil as ewu
reload(ewu)

from evernote.edam.type.ttypes import Note

note_template = """<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd">
<en-note style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;">
{0}
</en-note>"""

note = Note()
note.title = "hello from ipython"
note.content = note_template.format("hello from Canada 2")
note.tagNames = ["hello world"]

note = ewu.noteStore.createNote(note)

note.guid

In [ ]:
assert False

Move Evernote tags to have a different parent


In [ ]:
from evernote.edam.type.ttypes import Tag
import EvernoteWebUtil as ewu

tags = ewu.noteStore.listTags()
tags_by_name = dict([(tag.name, tag) for tag in tags])

print tags_by_name['+JoinTheAction'], tags_by_name['.Active Projects']

# update +JoinTheAction tag to put it underneath .Active Projects

jta_tag = tags_by_name['+JoinTheAction']
jta_tag.parentGuid = tags_by_name['.Active Projects'].guid

result = ewu.noteStore.updateTag(Tag(name=jta_tag.name, guid=jta_tag.guid, parentGuid=tags_by_name['.Active Projects'].guid))
print result

# mark certain project as inactive

result = ewu.noteStore.updateTag(Tag(name="+Relaunch unglue.it", 
                 guid=tags_by_name["+Relaunch unglue.it"].guid, 
                 parentGuid=tags_by_name['.Inactive Projects'].guid))

In [ ]:
# getTag?

ewu.noteStore.getTag(tags_by_name['+JoinTheAction'].guid)

In [ ]:
tags_by_name["+Relaunch unglue.it"]

In [ ]:
result = ewu.noteStore.updateTag(ewu.authToken, Tag(name="+Relaunch unglue.it", 
                 guid=tags_by_name["+Relaunch unglue.it"].guid, 
                 parentGuid=tags_by_name['.Inactive Projects'].guid))