Parallel questions for inactive projects
In [1]:
import logging
import settings
import base64
from evernote.api.client import EvernoteClient
import EvernoteWebUtil as ewu
token = settings.authToken2
ewu.init(token)
#reload(ewu)
# logging
LOG_FILENAME = 'active_and_inactive_GTD_projects.log'
logging.basicConfig(filename=LOG_FILENAME,
level=logging.DEBUG,
)
client = EvernoteClient(token=token, sandbox=False)
userStore = client.get_user_store()
user = userStore.getUser()
print(user.username)
In [2]:
import ENML2HTML
from ENML2HTML import MediaStore, hex_decode
class OSFMediaStore(MediaStore):
def __init__(self, note_store, note_guid, note=None):
super(OSFMediaStore, self).__init__(note_store, note_guid)
self.note = note
self.resources_by_id = dict()
if (note is not None) and (note.resources is not None):
self.resources_by_id = dict([(resource.data.bodyHash, resource) for resource in self.note.resources])
def _get_resource_by_hash(self, hash_str):
"""
get resource by its hash
"""
hash_bin = hex_decode(hash_str)
if hash_bin in self.resources_by_id:
resource = self.resources_by_id[hash_bin]
else:
resource = self.note_store.getResourceByHash(self.note_guid, hash_bin, True, False, False)
return resource.data.body
def save(self, hash_str, mime_type):
# hash_str is the hash digest string of the resource file
# mime_type is the mime_type of the resource that is about to be saved
# you can get the mime type to file extension mapping by accessing the dict MIME_TO_EXTENSION_MAPPING
# retrieve the binary data
data = self._get_resource_by_hash(hash_str)
# some saving operation [ not needed for embedding into data URI]
# return the URL of the resource that has just been saved
# convert content to data:uri
# https://gist.github.com/jsocol/1089733
data64 = u''.join([row.decode('utf-8') for row in base64.encodestring(data).splitlines()])
return u'data:{};base64,{}'.format(mime_type, data64)
In [3]:
notebooks = ewu.noteStore.listNotebooks()
for n in notebooks:
print (n.name)
In [4]:
# let me download all the notes from a notebook
from itertools import islice
nb_notes = ewu.notes_metadata(includeTitle=True,
includeUpdated=True,
includeUpdateSequenceNum=True,
notebookGuid=ewu.notebook(name=':REFERENCE').guid)
In [14]:
def note_to_html(ewu, client, note_guid):
note = ewu.get_note(note_guid,
withContent=True,
withResourcesData=True)
note_store = client.get_note_store()
mediaStore = OSFMediaStore(note_store, nm.guid, note)
html = ENML2HTML.ENMLToHTML(note.content, pretty=True, header=False,
media_store=mediaStore)
return html
In [15]:
notes = list(ewu.notes(title='boot-camps/python at 2013-04-ucb · swcarpentry/boot-camps · GitHub'))
notes
Out[15]:
In [13]:
notes[0].guid
Out[13]:
In [ ]:
note = ewu.notes
In [ ]:
note = ewu.get_note
In [16]:
html = note_to_html(ewu, client, 'bd97615e-6fee-44b0-ba03-3860f1806f11')
html
Out[16]:
In [5]:
exceptions = []
for (i, nm) in enumerate(islice(nb_notes,None)):
note = ewu.get_note(nm.guid,
withContent=True,
withResourcesData=True)
note_store = client.get_note_store()
mediaStore = OSFMediaStore(note_store, nm.guid, note)
try:
html = ENML2HTML.ENMLToHTML(note.content, pretty=True, header=False,
media_store=mediaStore)
print (i, note.title, note.contentLength, len(html), len(note.resources) if note.resources is not None else 0)
except Exception as e:
print (i, nm.guid, note.title, e)
exceptions.append(e)
In [ ]:
print(html)
In [ ]:
note.resources
In [ ]:
'df3e567d6f16d040326c7a0ea29a4f41'.decode('hex') == resource.data.bodyHash
In [ ]:
b64encode(resource.data.bodyHash)
In [ ]:
resource.data.bodyHash
In [ ]:
# get all the notes in the :PROJECTS Notebook
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))
# accumulate all the tags that begin with "+" associated with notes in :PROJECTS notebook
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.guid, note.updateSequenceNum, datetime.datetime.fromtimestamp(note.updated/1000.), \
len(plus_tags) == 1
# TO DO: check that each note has one and only one tag that begins with "+"
In [ ]:
len(plus_tags_set)
In [ ]:
ewu.all_tags()
In [ ]:
[tag for tag in ewu._tags_by_name.keys() if tag.startswith("+")]
In [ ]:
len(_)
In [ ]:
# consolidate into one -- calculate "+" tags that are not covered in :PROJECTS notebook
import EvernoteWebUtil as ewu
reload(ewu)
import datetime
from itertools import islice
all_plus_tags = set(filter(lambda tag: tag.startswith("+"),
[tag.name for tag in ewu.all_tags(refresh=False)]))
projects_notes = list(islice(ewu.notes_metadata(includeTitle=True,
includeUpdated=True,
includeUpdateSequenceNum=True,
notebookGuid=ewu.notebook(name=':PROJECTS').guid), None))
project_plus_tags = set()
for note in projects_notes:
tags = ewu.noteStore.getNoteTagNames(note.guid)
plus_tags = [tag for tag in tags if tag.startswith("+")]
project_plus_tags.update(plus_tags)
all_plus_tags - project_plus_tags
In [ ]:
for proj_name in (all_plus_tags - project_plus_tags):
print proj_name[1:]
In [ ]:
# next step: generate a note in the :PROJECTS notebook with the same tag name (minus the beginning "+")
# http://dev.evernote.com/doc/articles/creating_notes.php
import EvernoteWebUtil as ewu
from evernote.edam.type.ttypes import Note
# put the note into the :PROJECTS notebook
projects_nb_guid = ewu.notebook(name=':PROJECTS').guid
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>"""
for tag_name in (all_plus_tags - project_plus_tags):
proj_name = tag_name[1:]
note = ewu.create_note(proj_name, " ", tagNames=[tag_name],
notebookGuid=projects_nb_guid)
In [ ]:
# all children of ".Active Projects" tag
[tag for tag in ewu.all_tags() if tag.parentGuid == ewu.tag(name=".Active Projects").guid]
In [ ]:
# make sure that + tags have the right parent (.Active Projects)
# THIS IS USEFUL
active_projects_tag = ewu.tag(name=".Active Projects")
inactive_projects_tag = ewu.tag(name=".Inactive Projects")
wayward_plus_tags = [tag for tag in ewu.all_tags(refresh=True) if tag.name.startswith("+") and tag.parentGuid != active_projects_tag.guid]
for tag in wayward_plus_tags:
print tag.name
tag.parentGuid = active_projects_tag.guid
ewu.noteStore.updateTag(tag)
In [ ]:
# get all the .When tags
from collections import defaultdict
when_tags = [tag for tag in ewu.all_tags(refresh=True) if tag.parentGuid == ewu.tag(name=".When").guid]
when_tags_guids = set([tag.guid for tag in when_tags])
when_tags_guids
note_tags = defaultdict(list)
action_notes = list(islice(ewu.notes_metadata(includeTitle=True,
includeUpdated=True,
includeUpdateSequenceNum=True,
includeTagGuids=True,
notebookGuid=ewu.notebook(name='Action Pending').guid), None))
# tags that have no .When tags whatsover
# ideally -- each action has one and only one .When tag
for note in action_notes:
tag_guids = note.tagGuids
if tag_guids is None:
tag_guids = []
tag_names = [ewu.tag(guid=g).name for g in tag_guids]
for tag_name in tag_names:
note_tags[tag_name].append(note)
if len(tag_guids) == 0:
note_tags['__UNTAGGED__'].append(note)
note_tags.keys()
In [ ]:
# deal with untagged notes
# note_tags['__UNTAGGED__']
# look at tags that begin with "-"
# how to retire an action?
# let's do some stuff by hand and then look at programming
to_clean = [t for t in note_tags.keys() if t.startswith("-")]
to_clean
In [ ]:
# we can take the ids that come from AppleScript and get the local folder location
# /Users/raymondyee/Library/Application Support/Evernote/accounts/Evernote/rdhyee/content/p11026/content.html
#path = "/Users/raymondyee/Library/Application Support/Evernote/accounts/Evernote/rdhyee/content/{0}/content.enml".format(note.id().split("/")[-1])
#path
In [ ]:
# with the exact title, you can look up the note, though it won't necessarily be unique.
list(ewu.notes("summarizing my attempts so far to access race/ethnicity data from 2010 Census"))
In [ ]:
reload(ewu)
ewu.web_api_notes_from_selection()
In [ ]:
# take selection and strip out the when tags
reload(ewu)
ewu.strip_when_tags_move_to_ref_nb_for_selection()
In [ ]:
# look for stray actions: ones that are tied to retired projects or yet to be activated projects
action_notes = list(islice(ewu.notes_metadata(includeTitle=True,
includeUpdated=True,
includeUpdateSequenceNum=True,
notebookGuid=ewu.notebook(name='Action Pending').guid), None))
len(action_notes)
# accumulate tags and compute a dict of tag -> notes, including notes with no project tag
In [ ]:
list(ewu.actions_for_project("+ProgrammableWeb"))
In [ ]:
# grab active project tags of selected item
ewu.project_tags_for_selected()
In [ ]:
# for each of the selected projects, print out actions
for proj_tag in ewu.project_tags_for_selected():
print proj_tag
for n in list(ewu.actions_for_project(proj_tag)):
print n.title
print
In [ ]:
ewu.strip_when_tags_move_to_ref_nb_for_selection()
In [ ]:
def retire_project(tag_name,
ignore_actions=False,
dry_run=False,
display_remaining_actions=True):
"""
Retire the project represented by tag_name
"""
tag = ewu.tag(name=tag_name)
# make sure tag_name starts with "+"
if not tag_name.startswith("+"):
return tag
# if ignore_actions is False, check whether are still associated actions for the project.
# if there are actions, then don't retire project. Optionally display actions in Evernote
if not ignore_actions:
associated_actions = list(ewu.actions_for_project(tag_name))
if len(associated_actions):
if display_remaining_actions:
from appscript import app
evnote = app('Evernote')
evnote.open_collection_window(with_query_string = '''notebook:"Action Pending" tag:"{0}"'''.format(tag_name))
return tag_name
# before just trying to turn the + to a -, check for existence of the new name.
# if the new name exists, we would delete the + tag and apply the - tag to the notes tied to the
# + tag
# let's take care of the simple case first
# do I have logic for finding all notes that have a given tag?
# tagging a set of notes with a given tag?
retired_tag_name = "-" + tag_name[1:]
if ewu.tag(retired_tag_name) is None:
tag.name = retired_tag_name
else:
raise Exception("{0} already exists".format(retired_tag_name))
# change parent reference
tag.parentGuid = ewu.tag('.Inactive Projects').guid
# move the project note (if it exists) from the project notebook to the retired project notebook
project_notes = ewu.notes_metadata(includeTitle=True, includeNotebookGuid=True,
tagGuids = [tag.guid],
notebookGuid=ewu.notebook(name=':PROJECTS').guid)
# with NoteMetadata, how to make change to the corresponding note?
# make use of
# http://dev.evernote.com/doc/reference/NoteStore.html#Fn_NoteStore_updateNote
for note in project_notes:
note.notebookGuid = ewu.notebook(name=":PROJECTS--RETIRED").guid
ewu.noteStore.updateNote(note)
# deal with the associated actions for the project
# apply changes to tag
ewu.noteStore.updateTag(tag)
return tag
In [ ]:
from itertools import islice
import appscript
# retire first selected project
for proj_tag in islice(ewu.project_tags_for_selected(),1):
retire_project(proj_tag, ignore_actions=False)
In [ ]:
ewu.strip_when_tags_move_to_ref_nb_for_selection()
In [ ]:
# first the project note
project_notes = list(ewu.notes_metadata(includeTitle=True, includeNotebookGuid=True,
tagGuids = [hackfsm_tag.guid],
notebookGuid=ewu.notebook(name=':PROJECTS').guid))
# with NoteMetadata, how to make change to the corresponding note?
# make use of
# http://dev.evernote.com/doc/reference/NoteStore.html#Fn_NoteStore_updateNote
for note in project_notes:
print note
note.notebookGuid = ewu.notebook(name=":PROJECTS--RETIRED").guid
In [ ]:
# let's practice moving notes between notebooks.
# create a new note in :INBOX
reload(ewu)
import datetime
note = ewu.create_note(title="hello1: {0}".format(datetime.datetime.now().isoformat()),
content = """I want some <b>bold</b> action.
<div>I want some <i>italics</i> performance.</div>""",
tagNames= ['testing', 'ipynb-generated'],
notebookGuid=ewu.notebook(name=':INBOX').guid)
note
In [ ]:
# and then move it to :REFERENCE
# http://dev.evernote.com/doc/reference/NoteStore.html#Fn_NoteStore_updateNote
note.notebookGuid = ewu.notebook(name=':REFERENCE').guid
ewu.noteStore.updateNote(note)
In [ ]:
ewu.notebook(name=":PROJECTS--RETIRED")
In [ ]:
from appscript import app
evnote = app('Evernote')
tag_name = "@GLUEJAR"
evnote.open_collection_window(with_query_string = '''notebook:"Action Pending" tag:"{0}"'''.format(tag_name))
In [ ]: