Skip to content

Commit

Permalink
Token authorization + test coverage.
Browse files Browse the repository at this point in the history
  • Loading branch information
dreikanter committed Sep 5, 2012
1 parent 2e281ac commit 19126c9
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 4 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Expand Up @@ -8,3 +8,6 @@ build
bin bin
sdist sdist
MANIFEST MANIFEST

# This file intended to keep pinboard API token
token.txt
12 changes: 8 additions & 4 deletions pinboard.py
Expand Up @@ -6,7 +6,7 @@
This library was built on top of Paul Mucur's original work on the python-delicious This library was built on top of Paul Mucur's original work on the python-delicious
which was supported for python 2.3. Morgan became a contributor and ported this library which was supported for python 2.3. Morgan became a contributor and ported this library
to pinboard.in when it was announced in December 2010 that delicious servers may be to pinboard.in when it was announced in December 2010 that delicious servers may be
shutting down. shutting down.
The port to pinboard resulted in the inclusion of gzip support The port to pinboard resulted in the inclusion of gzip support
Expand Down Expand Up @@ -165,7 +165,7 @@ def __init__(self, username=None, password=None, token=None):
sys.stderr.write("Initialising Pinboard Account object.\n") sys.stderr.write("Initialising Pinboard Account object.\n")


if token: if token:
self.__token = token self.__token = urllib.quote_plus(token)
opener = urllib2.build_opener() opener = urllib2.build_opener()
else: else:
auth_handler = urllib2.HTTPBasicAuthHandler() auth_handler = urllib2.HTTPBasicAuthHandler()
Expand Down Expand Up @@ -213,6 +213,10 @@ def __request(self, url):
if _debug: if _debug:
sys.stderr.write("Opening %s.\n" % url) sys.stderr.write("Opening %s.\n" % url)


if self.__token:
sep = '&' if '?' in url else '?'
url = "%s%sauth_token=%s" % (url, sep, self.__token)

try: try:
## for pinboard a gzip request is made ## for pinboard a gzip request is made
raw_xml = urllib2.urlopen(url) raw_xml = urllib2.urlopen(url)
Expand All @@ -223,7 +227,7 @@ def __request(self, url):
xml = gzipper.read() xml = gzipper.read()


except urllib2.URLError, e: except urllib2.URLError, e:
raise e raise e


self["headers"] = {} self["headers"] = {}
for header in raw_xml.headers.headers: for header in raw_xml.headers.headers:
Expand Down Expand Up @@ -426,7 +430,7 @@ def add(self, url, description, extended="", tags=(), date="", toread="no", repl
"""Add a new post to pinboard.in""" """Add a new post to pinboard.in"""
query = {} query = {}
query["url"] = url query["url"] = url
query ["description"] = description query["description"] = description
query["toread"] = toread query["toread"] = toread
query["replace"] = replace query["replace"] = replace
query["shared"] = shared query["shared"] = shared
Expand Down
95 changes: 95 additions & 0 deletions test.py
@@ -0,0 +1,95 @@
#!/usr/bin/env python

"""Python-Pinboard unit tests.
This script requires 'token.txt' file to be placed in the same directory.
Consider to backup your data before running this test on real account
or use dedicated sandbox account (the second approach is recommended).
NO WARRANTY OF ANY KIND IS EXPRESSED OR IMPLIED. YOU USE AT YOUR OWN
RISK. THE AUTHOR WILL NOT BE LIABLE FOR DATA LOSS, DAMAGES, LOSS OF PROFITS
OR ANY OTHER KIND OF LOSS WHILE USING OR MISUSING THIS SOFTWARE."""

import unittest
import sys
import time

sys.path.insert(0, '.')

import pinboard


TOKEN = 'token.txt'


def get_token():
try:
with open(TOKEN, 'r') as f:
return f.read().strip()
except:
print('error reading token from ' + TOKEN)
raise


def gate_tag_names(tags):
for tag in tags:
yield tag['name']


# TODO: Cover PinboardAccount functionality

class TestPinboardAccount(unittest.TestCase):

# PinboardAccount instance (new for each test)
__p = None

def setUp(self):
self.__p = pinboard.open(token=get_token())

def test_basics(self):
"""Add some test bookmark records and than delete them"""
p = self.__p
test_url = 'http://github.com'
test_tag = '__testing__'

# Adding a test bookmark
p.add(url=test_url,
description='GitHub',
extended='It\'s a GitHub!',
tags=(test_tag))

posts = p.posts(tag=test_tag)

# Looks like there is no immediate consistency between API inputs
# and outputs, that's why additional delays added here and below.
time.sleep(1)

# Bookmark was added
self.assertIs(type(posts), list)
self.assertTrue(posts)

time.sleep(1)

# Tags contains new tag
tags = p.tags()
self.assertTrue(type(tags), dict)
self.assertIn(test_tag, gate_tag_names(tags))

# Deleting test bookmark(s)
for post in posts:
p.delete(post['href'])

time.sleep(1)

# There are no posts with test tag
posts = p.posts(tag=test_tag)
self.assertFalse(posts)

# And no test tag any more
tags = p.tags()
self.assertNotIn(test_tag, gate_tag_names(tags))


if __name__ == '__main__':
unittest.main()

0 comments on commit 19126c9

Please sign in to comment.