• listing active projects
  • associate a tag with active projects
  • are thee tags all filed properly?

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)


rdhyee

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)

optimize the downloading of resources for a specific note

list of all notebooks


In [3]:
notebooks = ewu.noteStore.listNotebooks()

for n in notebooks:
    print (n.name)


RY Journal
:INBOX
:REFERENCE
:PROJECTS
:CORE
Action Pending
Completed
Working with Open Data 2013
:PROJECTS--RETIRED
:PUBLISHABLE
:PROJECTS--POTENTIAL
:PUBLISHED
UCD Talk
Laura's writing
:JOURNAL
Retired Action
Skitch
Raymond Yee's Notebook
OSF Notebook
NYT Cooking
Postach.io
PIM2020
Review

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]:
[NoteMetadata(updated=1367023696000, created=None, deleted=None, contentLength=None, title='boot-camps/python at 2013-04-ucb \xc2\xb7 swcarpentry/boot-camps \xc2\xb7 GitHub', notebookGuid=None, updateSequenceNum=22191, tagGuids=None, largestResourceMime=None, attributes=None, guid='bd97615e-6fee-44b0-ba03-3860f1806f11', largestResourceSize=None)]

In [13]:
notes[0].guid


Out[13]:
'bd97615e-6fee-44b0-ba03-3860f1806f11'

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]:
'<div>\n <br clear="none"/>\n <div style="position: relative">\n  <div style="font-size: 16px">\n   <div style="overflow-y:scroll;">\n    <div style="font-style:normal;font-variant:normal;font-weight:normal;font-size:13px;font-family:Helvetica, arial, freesans, clean, sans-serif;line-height:1.4;background-color:rgb(255, 255, 255);color:rgb(51, 51, 51);-webkit-user-select:auto;">\n     <div>\n      <div>\n       <div>\n        <div>\n         <div style="overflow:hidden;">\n          <div style="min-height:669px;">\n           <div>\n            <div style="background-color:rgb(238, 238, 238);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;">\n             <span style="margin:0px;padding:10px;border:0px;font-size:16px;line-height:20px;font-weight:bold;color:rgb(85, 85, 85);text-shadow:rgb(255, 255, 255) 0px 1px 0px;display:block;border-width:1px 1px 0px;border-style:solid solid none;border-top-color:rgb(202, 202, 202);border-right-color:rgb(202, 202, 202);border-left-color:rgb(202, 202, 202);background-color:rgb(234, 234, 234);background-image:linear-gradient(rgb(250, 250, 250), rgb(234, 234, 234));background-repeat:repeat no-repeat;">\n              <span style="margin:0px;padding:0px;border:0px;font-family:\'Octicons Regular\';font-weight:normal;font-style:normal;display:inline-block;-webkit-font-smoothing:antialiased;line-height:1;text-decoration:none;font-size:16px;width:16px;height:16px;">\n               <span style="font-family:\'Octicons Regular\';font-weight:normal;font-style:normal;line-height:1;font-size:16px;">\n                \xef\x80\x87\n               </span>\n              </span>\n              README.md\n             </span>\n             <div style="margin:0px;padding:30px;border:1px solid rgb(202, 202, 202);display:block;font-size:14px;line-height:1.6;overflow:hidden;background-color:rgb(255, 255, 255);">\n              <h1 style="margin:20px 0px 10px;padding:0px;border:0px;font-weight:bold;-webkit-font-smoothing:antialiased;cursor:text;position:relative;font-size:28px;color:rgb(0, 0, 0);margin-top:0px;padding-top:0px;">\n               <a href="https://github.com/swcarpentry/boot-camps/tree/2013-04-ucb/python#scientific-python-basics" name="scientific-python-basics" shape="rect" style="margin:0px;padding:0px;border:0px;color:rgb(65, 131, 196);text-decoration:none;display:block;padding-left:30px;margin-left:-30px;cursor:pointer;position:absolute;top:0px;left:0px;bottom:0px;">\n               </a>\n               Scientific Python Basics\n              </h1>\n              <h2 style="margin:20px 0px 10px;padding:0px;border:0px;font-weight:bold;-webkit-font-smoothing:antialiased;cursor:text;position:relative;font-size:24px;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(204, 204, 204);color:rgb(0, 0, 0);margin-top:0px;padding-top:0px;">\n               <a href="https://github.com/swcarpentry/boot-camps/tree/2013-04-ucb/python#goals" name="goals" shape="rect" style="margin:0px;padding:0px;border:0px;color:rgb(65, 131, 196);text-decoration:none;display:block;padding-left:30px;margin-left:-30px;cursor:pointer;position:absolute;top:0px;left:0px;bottom:0px;">\n               </a>\n               Goals\n              </h2>\n              <p style="margin:15px 0px;padding:0px;border:0px;margin-top:0px;">\n               Despite what the title above might suggest, the purpose of this Software \nCarpentry bootcamp is\n               <strong style="margin:0px;padding:0px;border:0px;font-weight:bold;">\n                not\n               </strong>\n               to teach you how to program in Python. While we \ndo love Python for scientific computing, the goals of these modules is actually \nto teach you the basic, core concepts of programming that transcend languages, \nhow they fit together, and how you can use them to become a better scientist.\n              </p>\n              <p style="margin:15px 0px;padding:0px;border:0px;">\n               By the end of these scientific Python lessons, you will be able to:\n              </p>\n              <ol style="margin:15px 0px;padding:0px;border:0px;padding-left:30px;">\n               <li style="margin:0px;padding:0px;border:0px;">\n                Describe and distinguish the seven core elements shared by all programming \nlanguages.\n               </li>\n               <li style="margin:0px;padding:0px;border:0px;">\n                Use Python to write simple programs that use these core elements, using \nboth the core library and scientific packages such as numpy.\n               </li>\n               <li style="margin:0px;padding:0px;border:0px;">\n                Make and save simple publication-quality plots using matplotlib.\n               </li>\n               <li style="margin:0px;padding:0px;border:0px;">\n                Read, manipulate, and save data files in csv and text formats.\n               </li>\n               <li style="margin:0px;padding:0px;border:0px;">\n                Write unit tests to confirm the accuracy of your Python code.\n               </li>\n               <li style="margin:0px;padding:0px;border:0px;">\n                Create standalone Python scripts that can be run from the command line.\n               </li>\n              </ol>\n              <p style="margin:15px 0px;padding:0px;border:0px;">\n               We (the instructors) recognize that you all unavoidably have come with very \ndifferent levels of background in Python programming. We expect that some of \nyou might be experienced in basic Python and a few of you of you have \nexperience with additional modules such as numpy and scipy - for those in that \ncategory, this section of the workshop may not be as novel as the other \nsections. However, we hope that the method of presentation will help to \nsolidify your existing knowledge. We also encourage you to take the opportunity \nto ask the instructors and volunteers about more advanced techniques that you \nmight have heard of but do not know how to use well.\n              </p>\n              <p style="margin:15px 0px;padding:0px;border:0px;">\n               For those who have no (or almost no) background in programming in any language, \nyou may find that these lessons proceed quickly. We encourage you to make \nliberal use of the helpful volunteers as we proceed through these lessons. You \nmay also wish to consider working together with a partner to complete the \nexercises as a team.\n              </p>\n              <p style="margin:15px 0px;padding:0px;border:0px;">\n               Regardless of your background, you will probably feel like trying to take in \nall of this material is like trying to drink from a firehose. That\'s OK - the \nidea is to at least introduce you to a wide variety of topics, with the hope \nthat you (a) will get to reinforce the most important concepts during \nexercises, and (b) will be able to come back to these materials later to \ncontinue mastering the concepts.\n              </p>\n              <p style="margin:15px 0px;padding:0px;border:0px;">\n               As an analogy for our overall strategy for teaching Python, picture becoming a \nscientific programmer as constructing a house. First you pour the foundation, \nthen you frame the house with wood beams, then you put on a roof, seal it up, \nand furnish it (or something like that). We are hoping that many of you have \narrived today with the foundation already poured - that is, you understand \nbasically how to get some things done using small scripts or programs in some \nlanguage. In these lessons, we will mostly focus on constructing the frame of \nthe house together by putting in place the major structures and concepts that \nsupport all scientific programs. Once the workshop is over, you\'ll need to go \nout on your own and fill in this structure with drywall, insulation, and a \ncouch. (We\'ll try to point out some useful fixtures that you might want to add \nto your house as we go along.)\n              </p>\n              <h2 style="margin:20px 0px 10px;padding:0px;border:0px;font-weight:bold;-webkit-font-smoothing:antialiased;cursor:text;position:relative;font-size:24px;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(204, 204, 204);color:rgb(0, 0, 0);">\n               <a href="https://github.com/swcarpentry/boot-camps/tree/2013-04-ucb/python#the-seven-core-concepts" name="the-seven-core-concepts" shape="rect" style="margin:0px;padding:0px;border:0px;color:rgb(65, 131, 196);text-decoration:none;display:block;padding-left:30px;margin-left:-30px;cursor:pointer;position:absolute;top:0px;left:0px;bottom:0px;">\n               </a>\n               The Seven Core Concepts\n              </h2>\n              <p style="margin:15px 0px;padding:0px;border:0px;margin-top:0px;">\n               As noted by Greg Wilson (the founder of Software Carpentry), every programming \nlanguage shares\n               <a href="http://software-carpentry.org/2012/08/applying-pedagogical-principles-in-this-course/" shape="rect" style="margin:0px;padding:0px;border:0px;color:rgb(65, 131, 196);text-decoration:none;">\n                seven core elements\n               </a>\n               :\n              </p>\n              <ol style="margin:15px 0px;padding:0px;border:0px;padding-left:30px;">\n               <li style="margin:0px;padding:0px;border:0px;">\n                Individual things (the number 2, the string \'hello\', a matplotlib figure)\n               </li>\n               <li style="margin:0px;padding:0px;border:0px;">\n                Commands that operate on things (the + symbol, the\n                <code style="margin:0px 2px;padding:0px 5px;border:1px solid rgb(234, 234, 234);font-size:12px;font-family:Consolas, \'Liberation Mono\', Courier, monospace;background-color:rgb(248, 248, 248);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;white-space:nowrap;margin-top:0px;">\n                 len\n                </code>\n                function)\n               </li>\n               <li style="margin:0px;padding:0px;border:0px;">\n                Groups of things (Python lists, tuples, and dictionaries)\n               </li>\n               <li style="margin:0px;padding:0px;border:0px;">\n                Ways to repeat yourself (for and while loops)\n               </li>\n               <li style="margin:0px;padding:0px;border:0px;">\n                Ways to make choices (if and try statements)\n               </li>\n               <li style="margin:0px;padding:0px;border:0px;">\n                Ways to create chunks (functions, objects/classes, and modules)\n               </li>\n               <li style="margin:0px;padding:0px;border:0px;">\n                Ways to combine chunks (function composition)\n               </li>\n              </ol>\n              <p style="margin:15px 0px;padding:0px;border:0px;">\n               The lines between these are often blurry in practice - for example, a string in \nPython actually mixes some characteristics of a thing, a group, and a "chunk". \nThe distinctions between these categories is not particularly relevant to the \ncomputer - they are purely a conceptual framework that helps programmers write \ncode that does what they want it to do.\n              </p>\n              <p style="margin:15px 0px;padding:0px;border:0px;">\n               We expect that you\'ll find the basics of 1 and 2 fairly straightforward. We\'ll \ngo quickly through those and will spend the most time on items 3-6. We won\'t \nreally talk about 7, as it is not as common in scientific Python programming as \nit is in, say, shell scripting (pipes and redirection).\n              </p>\n              <p style="margin:15px 0px;padding:0px;border:0px;">\n               Don\'t worry if you don\'t already know what all of the above examples mean - \nyou\'ll know by the end of this lesson.\n              </p>\n              <h2 style="margin:20px 0px 10px;padding:0px;border:0px;font-weight:bold;-webkit-font-smoothing:antialiased;cursor:text;position:relative;font-size:24px;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(204, 204, 204);color:rgb(0, 0, 0);">\n               <a href="https://github.com/swcarpentry/boot-camps/tree/2013-04-ucb/python#starting-an-ipython-notebook" name="starting-an-ipython-notebook" shape="rect" style="margin:0px;padding:0px;border:0px;color:rgb(65, 131, 196);text-decoration:none;display:block;padding-left:30px;margin-left:-30px;cursor:pointer;position:absolute;top:0px;left:0px;bottom:0px;">\n               </a>\n               Starting an IPython Notebook\n              </h2>\n              <p style="margin:15px 0px;padding:0px;border:0px;margin-top:0px;">\n               To learn about these core concepts and the Python language, we\'ll start off by \nworking within the IPython notebook.\n              </p>\n              <p style="margin:15px 0px;padding:0px;border:0px;">\n               To start up a notebook, open Terminal and navigate to the folder containing the \nipynb notebook files that you wish to open (or to any directory in which you\'d \nlike to save a new notebook, if you\'re creating a new notebook from scratch). \nOnce in the directory, run the command\n               <code style="margin:0px 2px;padding:0px 5px;border:1px solid rgb(234, 234, 234);font-size:12px;font-family:Consolas, \'Liberation Mono\', Courier, monospace;background-color:rgb(248, 248, 248);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;white-space:nowrap;">\n                ipython notebook\n               </code>\n               , which will launch a \nlocal webserver and open your default browser. From there you can open an \nexisting notebook, create a new notebook, and start working.\n              </p>\n              <p style="margin:15px 0px;padding:0px;border:0px;">\n               Note that if you are on a Windows machine, this command will probably not run \nin Git bash or Cygwin. Instead, open a Command Prompt (click on the Start menu \nand type\n               <code style="margin:0px 2px;padding:0px 5px;border:1px solid rgb(234, 234, 234);font-size:12px;font-family:Consolas, \'Liberation Mono\', Courier, monospace;background-color:rgb(248, 248, 248);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;white-space:nowrap;">\n                cmd\n               </code>\n               in the search box for Windows 7, or click on Run then type cmd \nfor Windows XP), navigate to the appropriate directory, and run the command\n               <code style="margin:0px 2px;padding:0px 5px;border:1px solid rgb(234, 234, 234);font-size:12px;font-family:Consolas, \'Liberation Mono\', Courier, monospace;background-color:rgb(248, 248, 248);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;white-space:nowrap;">\n                ipython notebook\n               </code>\n               .\n              </p>\n              <h2 style="margin:20px 0px 10px;padding:0px;border:0px;font-weight:bold;-webkit-font-smoothing:antialiased;cursor:text;position:relative;font-size:24px;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(204, 204, 204);color:rgb(0, 0, 0);">\n               <a href="https://github.com/swcarpentry/boot-camps/tree/2013-04-ucb/python#asking-questions" name="asking-questions" shape="rect" style="margin:0px;padding:0px;border:0px;color:rgb(65, 131, 196);text-decoration:none;display:block;padding-left:30px;margin-left:-30px;cursor:pointer;position:absolute;top:0px;left:0px;bottom:0px;">\n               </a>\n               Asking Questions\n              </h2>\n              <p style="margin:15px 0px;padding:0px;border:0px;margin-top:0px;">\n               As we go through this lesson, you can ask questions in two ways:\n              </p>\n              <ol style="margin:15px 0px;padding:0px;border:0px;padding-left:30px;margin-bottom:0px;">\n               <li style="margin:0px;padding:0px;border:0px;">\n                If you have a question for me, just raise your hand and ask.\n               </li>\n               <li style="margin:0px;padding:0px;border:0px;">\n                If you have a question that you think might be restricted to just you (like \nsomething on your computer isn\'t working), raise your hand an a volunteer \nwill come over to help you individually.\n               </li>\n              </ol>\n             </div>\n             <span style="display:block;height:0px;clear:both;visibility:hidden;">\n              .\n             </span>\n            </div>\n           </div>\n          </div>\n         </div>\n        </div>\n       </div>\n      </div>\n     </div>\n    </div>\n   </div>\n  </div>\n </div>\n <br clear="none"/>\n</div>'

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)


/Users/raymondyee/anaconda/envs/myenv/lib/python2.7/site-packages/bs4/__init__.py:181: UserWarning: No parser was explicitly specified, so I'm using the best available HTML parser for this system ("lxml"). This usually isn't a problem, but if you run this code on another system, or in a different virtual environment, it may use a different parser and behave differently.

The code that caused this warning is on line 174 of the file /Users/raymondyee/anaconda/envs/myenv/lib/python2.7/runpy.py. To get rid of this warning, change code that looks like this:

 BeautifulSoup(YOUR_MARKUP})

to this:

 BeautifulSoup(YOUR_MARKUP, "lxml")

  markup_type=markup_type))
(0, 'Abandoned mattress with an attitude', 201, 1575374, 1)
(1, 'opera2', 436, 325, 0)
(2, 'The Developer Perspective: Building an App That Works With Evernote \xc2\xab Evernote Blogcast', 332, 229, 0)
(3, 'AppleScript and Automator Resources | Veritrope', 287, 184, 0)
(4, 'Repetitive Strain Injury: How to prevent, identify, and manage RSI', 311, 218, 0)
(5, 'RSI Action\xe2\x80\xa6 \xc2\xbb Guide for Young People: How to Avoid RSI', 431, 338, 0)
(6, 'Hacker News | How I Cured my RSI Pain', 330, 234, 0)
(7, 'Hacker News | Poll: How do you combat RSI?', 330, 234, 0)
(8, 'Hacker News | Ask HN: Remedies for RSI?', 328, 232, 0)
(9, 'IMAK Smart Glove with Thumb Support for RSI & CTS Hand Pain (Medium):Amazon:Health & Beauty', 354, 261, 0)
(10, 'Welcome to the RSI Awareness Website', 364, 268, 0)
(11, "Verizon: unlimited 3G customers can upgrade to 4G, keep data pack and grab $30 tethering' article", 296, 200, 0)
(12, 'CT meeting agenda making', 3891, 3856, 0)
(13, 'clpgh carnegie public library card #', 253, 125, 0)
(14, 'Robert K. Logan', 501, 423, 0)
(15, 'Cheryl Towers', 12398, 13284, 0)
(16, 'prime reports', 305, 195, 0)
(17, 'GTD', 354, 256, 0)
(18, 'running regluit and unglu on Mac and ry-dev', 2190, 2418, 0)
(19, 'git surprises when trying to update local master', 811, 855, 0)
(20, 'Testing unglue.it, especially on the selenium front', 31922, 30801, 0)
(21, 'Data Unbound taxes 2010', 328, 211, 0)
(22, 'status of Data Unbound taxes 2010', 1164, 1190, 0)
(23, 'assign tasks for Jason', 904, 874, 0)
(24, 'Calculating the fingerprint of Amazon EC2 ssh key / keypairs', 4206, 4616, 0)
(25, 'How to create a self-signed Certificate', 4089, 4604, 0)
(26, 'make a mechanical turk job with boto \xe2\x80\x94 Gist', 306, 210, 0)
(27, 'wifi settings for Holly, Janice, and Shirley/Dad', 376, 321, 0)
(28, 'applying ubuntu security upgrades', 702, 615, 0)
(29, 'Amazon DynamoDB \xe2\x80\x93 a Fast and Scalable NoSQL Database Service from AWS | Hacker News', 330, 234, 0)
(30, 'Can Touch Screens Hurt You? - Technology Review', 2874, 2816, 0)
(31, 'Useful to know that we can buy AWS premium support', 378, 282, 0)
(32, 'responding to PA tax summons', 4115, 4674, 0)
(33, 'where to park in North Berkeley', 469, 120684, 1)
(34, 'get celerybeat running as a daemon', 3673, 4072, 0)
(35, 'Surprise: HTC Rezound is a Global GSM/HSPA Ready Device', 640, 1778, 1)
(36, 'Possible payment gateway solutions for SFPlatform | Agriya Dev Blog', 47494, 48560, 0)
(37, 'running support_campaign in unglue.it (selenium)', 8757, 10322, 0)
(38, 'secure deletion of files in linux', 549, 450, 0)
(39, 'closing our campaigns -- django-admin shell campaigns I used', 2876, 3223, 0)
(40, 'unglue.it: who has pledged the most money so far?', 5921, 6877, 0)
(41, 'Data Miner \xe2\x80\x94 GitHub Jobs', 12714, 52711, 2)
---------------------------------------------------------------------------
EDAMSystemException                       Traceback (most recent call last)
<ipython-input-5-2c612f6a88cc> in <module>()
      7                 withResourcesData=True)
      8 
----> 9     note_store = client.get_note_store()
     10     mediaStore = OSFMediaStore(note_store, nm.guid, note)
     11 

/Users/raymondyee/anaconda/envs/myenv/lib/python2.7/site-packages/evernote/api/client.pyc in get_note_store(self)
     66     def get_note_store(self):
     67         user_store = self.get_user_store()
---> 68         note_store_uri = user_store.getNoteStoreUrl()
     69         store = Store(self.token, NoteStore.Client, note_store_uri)
     70         if not store:  # Trick for PyDev code completion

/Users/raymondyee/anaconda/envs/myenv/lib/python2.7/site-packages/evernote/api/client.pyc in delegate_method(*args, **kwargs)
    136                 return functools.partial(
    137                     targetMethod, authenticationToken=self.token
--> 138                 )(**dict(zip(arg_names, args)))
    139             else:
    140                 return targetMethod(*args, **kwargs)

/Users/raymondyee/anaconda/envs/myenv/lib/python2.7/site-packages/evernote/edam/userstore/UserStore.pyc in getNoteStoreUrl(self, authenticationToken)
   1154     """
   1155     self.send_getNoteStoreUrl(authenticationToken)
-> 1156     return self.recv_getNoteStoreUrl()
   1157 
   1158   def send_getNoteStoreUrl(self, authenticationToken):

/Users/raymondyee/anaconda/envs/myenv/lib/python2.7/site-packages/evernote/edam/userstore/UserStore.pyc in recv_getNoteStoreUrl(self)
   1179       raise result.userException
   1180     if result.systemException is not None:
-> 1181       raise result.systemException
   1182     raise TApplicationException(TApplicationException.MISSING_RESULT, "getNoteStoreUrl failed: unknown result");
   1183 

EDAMSystemException: EDAMSystemException(errorCode=19, rateLimitDuration=3367, _message=None)

In [ ]:
print(html)

In [ ]:
note.resources

In [ ]:
'df3e567d6f16d040326c7a0ea29a4f41'.decode('hex') == resource.data.bodyHash

In [ ]:
b64encode(resource.data.bodyHash)

In [ ]:
resource.data.bodyHash

list of all projects


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)

utility for deactivating an active project

Steps:

  • rename tag "+TagName" to "-TagName" (checking for possible name collision)
  • move the new tag to be a child of the .Inactive Projects tag
  • move the note to Projects Retired

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

How to retire an action

  • strip action of all .when tags
  • move action to Retired Action Notebook / Reference

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

Practice making an :INBOX and moving it to :REFERENCE notebook


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")

Applescripting?


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 [ ]: