usage

to use shaffer’s hypothesis script:

1 - has to run in python 3 2 - uncomment d = json.loads(h.text) and comment out the d = ast.literal_eval(h.text) 3 - i pasted the pypothesis.py into my grabH.py script 4 - had to run a virtualenv: virtualenv -p python3 grabH 5 - activate: source env/bin/grabH 6 - run the script: ‘python grabH.py’ 7 - copy the result to the notebook posts folder.

script:



import requests
import json
import ast

# pypothesis.py script pasted here cause frustrated
class Annotation():

    def __init__(self, jsondata):
        self.jsondata = jsondata

        # title of annotated article
        self.title = self.jsondata['document']['title'][0].replace('\n', '').replace('\r', '')

        # uri of annotated article
        self.uri = self.jsondata['uri']

        # highlighted text in annotated article
        if 'selector' in self.jsondata['target'][0].keys():
            selector = self.jsondata['target'][0]['selector']
            for entry in selector:
                if 'exact' in entry.keys():
                    self.highlight = entry['exact'].replace('\n', ' ').replace('\r', ' ')
                else:
                    self.highlight = 'No highlighted text found.'
        else:
            self.highlight = 'No highlighted text found.'

        # annotation comment
        if self.jsondata['text']:
            self.comment = self.jsondata['text']
        else:
            self.comment = 'No comment found.'

        # user that generated the annotation
        self.user = self.jsondata['user'].split(':')[1].split('@')[0]

        # date/time created and updated
        self.created = self.jsondata['created']
        self.updated = self.jsondata['updated']

        # hypothesis ID & annotation URL
        self.id = self.jsondata['id']
        self.hypothesisurl = 'https://hyp.is/' + self.jsondata['id']

def retrieve(apiurl):
    # takes the hypothes.is API URL for an annotation and returns JSON data
    h = requests.get(apiurl)
    d = json.loads(h.text)
    return d

def retrievelist(searchurl):
    # takes a hypothes.is API search URL returns JSON data for each element as a list of individual annotations
    h = requests.get(searchurl)
    d = json.loads(h.text)
    jsonlist = []
    for entry in d['rows']:
        jsonlist.append(entry)
    return jsonlist

def apiurl(hypurl):
    # takes the hyp.is URL provided in an annotation and returns the API URL (for use elsewhere in this module)
    hypid = hypurl.split('.is/')[1].split('/')[0]
    url = 'https://hypothes.is/api/annotations/' + hypid
    return url

def searchurl(user = '', tag = '', tags = []):
    """
    Returns a well-formed URL for querying the hypothes.is API.
    A hypothes.is username is optional.
    Use *either* tag or tags, not both. You can also use neither if a username is provided.
    Use tag for a single tag, and put the tag in quotes.
    Use tags for multiple tags, and enclose them in a list: ['tag1', 'tag2', 'tag3'].
    searchurl() only works if at least once term (user, tag, or tags) is provided.
    """

    source = 'https://hypothes.is/api/search?'
    conn = '&'
    usercall = 'user='
    tagcall = 'tags='
    if tags == []:
        if user != '' and tag != '':
            return source + usercall + user + conn + tagcall + tag
        if user == '' and tag != '':
            return source + tagcall + tag
        if user != '' and tag == '':
            return source + usercall + user
        if user == '' and tag == '':
            print('No search parameters included.')
    if tags != []:
        if user != '':
            sourcestring = source + usercall + user
            for entry in tags:
                sourcestring += (conn + tagcall + entry)
            return sourcestring
        if user == '':
            sourcestring = source + tagcall + tags.pop(0)
            while tags != []:
                sourcestring += (conn + tagcall + tags.pop(0))
            return sourcestring
###

source = 'https://hypothes.is/api/search?'
conn = '&'
usercall = 'user='
tagcall = 'tags='

# adjust these variables for different searches
# also be sure to adjust the page title in the YAML header section
user = 'shawn.graham@hypothes.is'
tags = ''
# search string for fetching annotations from a specific user using a specific tag:
#     searchstring = source + usercall + user + conn + tagcall + tags
# search string for fetching all annotations from a specific user:
searchstring = source + usercall + user
# search string for fetching all annotations from any user, but limited to a specific tag (a class hashtag, for example):
#     searchstring = source + tagcall + tags
filename = '2017-06-23-hypothesis-annotations.md'

# YAML header
headerinfo = '---\n'
headerinfo += 'layout: post\n'
headerinfo += 'title: "Hypothes.is annotations"\n'
headerinfo += 'date: 2017-06-23 13:37:00 -0500\n' # need to make this automatic
headerinfo += 'categories:\n'
headerinfo += '- Reading Notes'
headerinfo += '---\n\n'

# don't edit anything below this line unless you know what you're doing :)
def writeMarkdown(header, data, filename):
    f = open(filename, 'w')
    f.write(header)
    for line in data:
        f.write(str(line) + '\n')

def markdown(annotation):
    # title of post with link to original post
    textout = '['
    textout += annotation['document']['title'][0].replace('\n', '').replace('\r', '')
    textout += ']('
    textout += annotation['uri']
    textout += ')\n\n'

    # grab highlighted portion of post
    if 'selector' in annotation['target'][0].keys():
        selector = annotation['target'][0]['selector']
        for entry in selector:
            if 'exact' in entry.keys():
                targetInfo = entry['exact'].replace('\n', ' ').replace('\r', ' ')
            else:
                targetInfo = 'No highlighted text found.'
    else:
        targetInfo = 'No highlighted text found.'

    # highlighted portion of post as blockquote
    textout += '> '
    textout += targetInfo
    textout += '\n\n'

    # annotation comment, with username and link to stream
    if annotation['text']:
        textout += annotation['text']
        textout += '\n'
    textout += '(Curated by ['
    useracct = annotation['user'].split(':')[1].split('@')[0]
    textout += useracct
    textout += ']('
    textout += 'https://hypothes.is/stream?=user:'
    textout += useracct
    textout += '))\n\n<hr/>\n'
    return textout

# run
h = requests.get(searchstring)
#retained in case needed for valid unicode in JSON
d = json.loads(h.text)
# d = ast.literal_eval(h.text)


dataToWrite = []
i = 0
for row in d['rows']:
    dataToWrite.append(markdown(d['rows'][i]))
    i += 1
writeMarkdown(headerinfo, dataToWrite, filename)