From d8e874aad655e3ac0499f6995d9cef7ce9b9fbdc Mon Sep 17 00:00:00 2001 From: sneakypete81 Date: Sun, 28 Jul 2013 18:40:27 +0100 Subject: [PATCH 01/19] PyLint tweaks. Added .pylint-ignores patchfile, with waived PyLint warnings --- trovebox/.pylint-ignores.patch | 224 +++++++++++++++++++++++++++++++++ trovebox/api_album.py | 7 +- trovebox/api_photo.py | 7 +- trovebox/api_tag.py | 4 +- trovebox/config.py | 5 +- trovebox/http.py | 2 +- trovebox/main.py | 5 +- trovebox/objects.py | 8 +- 8 files changed, 250 insertions(+), 12 deletions(-) create mode 100644 trovebox/.pylint-ignores.patch diff --git a/trovebox/.pylint-ignores.patch b/trovebox/.pylint-ignores.patch new file mode 100644 index 0000000..26a95cb --- /dev/null +++ b/trovebox/.pylint-ignores.patch @@ -0,0 +1,224 @@ +diff --unified --recursive '--exclude=.pylint-ignores.patch' ./api_album.py /tmp/pylint_iHIz1e/api_album.py +--- ./api_album.py 2013-07-28 18:32:55.587158750 +0100 ++++ /tmp/pylint_iHIz1e/api_album.py 2013-07-28 18:32:52.783144848 +0100 +@@ -1,6 +1,6 @@ + from .objects import Album + +-class ApiAlbums(object): ++class ApiAlbums(object): # pylint: disable=R0903,C0111 + def __init__(self, client): + self._client = client + +@@ -9,7 +9,7 @@ + results = self._client.get("/albums/list.json", **kwds)["result"] + return [Album(self._client, album) for album in results] + +-class ApiAlbum(object): ++class ApiAlbum(object): # pylint: disable=C0111 + def __init__(self, client): + self._client = client + +diff --unified --recursive '--exclude=.pylint-ignores.patch' ./api_photo.py /tmp/pylint_iHIz1e/api_photo.py +--- ./api_photo.py 2013-07-28 18:32:55.587158750 +0100 ++++ /tmp/pylint_iHIz1e/api_photo.py 2013-07-28 18:32:52.787144864 +0100 +@@ -17,7 +17,7 @@ + ids.append(photo) + return ids + +-class ApiPhotos(object): ++class ApiPhotos(object): # pylint: disable=C0111 + def __init__(self, client): + self._client = client + +@@ -51,7 +51,7 @@ + raise TroveboxError("Delete response returned False") + return True + +-class ApiPhoto(object): ++class ApiPhoto(object): # pylint: disable=C0111 + def __init__(self, client): + self._client = client + +diff --unified --recursive '--exclude=.pylint-ignores.patch' ./api_tag.py /tmp/pylint_iHIz1e/api_tag.py +--- ./api_tag.py 2013-07-28 18:32:55.587158750 +0100 ++++ /tmp/pylint_iHIz1e/api_tag.py 2013-07-28 18:32:52.787144864 +0100 +@@ -1,6 +1,6 @@ + from .objects import Tag + +-class ApiTags(object): ++class ApiTags(object): # pylint: disable=R0903,C0111 + def __init__(self, client): + self._client = client + +@@ -9,7 +9,7 @@ + results = self._client.get("/tags/list.json", **kwds)["result"] + return [Tag(self._client, tag) for tag in results] + +-class ApiTag(object): ++class ApiTag(object): # pylint: disable=C0111 + def __init__(self, client): + self._client = client + +diff --unified --recursive '--exclude=.pylint-ignores.patch' ./config.py /tmp/pylint_iHIz1e/config.py +--- ./config.py 2013-07-28 18:32:55.587158750 +0100 ++++ /tmp/pylint_iHIz1e/config.py 2013-07-28 18:32:52.787144864 +0100 +@@ -1,7 +1,7 @@ + from __future__ import unicode_literals + import os + try: +- from configparser import ConfigParser # Python3 ++ from configparser import ConfigParser # Python3 # pylint: disable=F0401 + except ImportError: + from ConfigParser import SafeConfigParser as ConfigParser # Python2 + try: +@@ -9,8 +9,8 @@ + except ImportError: + import StringIO as io # Python2 + +-class Config(object): +- def __init__(self, config_file, host, ++class Config(object): # pylint: disable=R0903,C0111 ++ def __init__(self, config_file, host, # pylint: disable=R0913 + consumer_key, consumer_secret, + token, token_secret): + if host is None: +@@ -65,7 +65,7 @@ + parser = ConfigParser() + parser.optionxform = str # Case-sensitive options + try: +- parser.read_file(buf) # Python3 ++ parser.read_file(buf) # Python3 # pylint: disable=E1103 + except AttributeError: + parser.readfp(buf) # Python2 + +diff --unified --recursive '--exclude=.pylint-ignores.patch' ./http.py /tmp/pylint_iHIz1e/http.py +--- ./http.py 2013-07-28 18:32:55.591158774 +0100 ++++ /tmp/pylint_iHIz1e/http.py 2013-07-28 18:32:52.787144864 +0100 +@@ -4,18 +4,18 @@ + import requests_oauthlib + import logging + try: +- from urllib.parse import urlunparse # Python3 ++ from urllib.parse import urlunparse # Python3 # pylint: disable=F0401,E0611 + except ImportError: + from urlparse import urlunparse # Python2 + + from .objects import TroveboxObject +-from .errors import * ++from .errors import * # pylint: disable=W0401 + from .config import Config + + if sys.version < '3': +- TEXT_TYPE = unicode ++ TEXT_TYPE = unicode # pylint: disable=C0103 + else: +- TEXT_TYPE = str ++ TEXT_TYPE = str # pylint: disable=C0103 + + DUPLICATE_RESPONSE = {"code": 409, + "message": "This photo already exists"} +@@ -32,7 +32,7 @@ + This should be used to ensure that your application will continue to work + even if the Trovebox API is updated to a new revision. + """ +- def __init__(self, config_file=None, host=None, ++ def __init__(self, config_file=None, host=None, # pylint: disable=R0913 + consumer_key='', consumer_secret='', + token='', token_secret='', api_version=None): + self._api_version = api_version +diff --unified --recursive '--exclude=.pylint-ignores.patch' ./__init__.py /tmp/pylint_iHIz1e/__init__.py +--- ./__init__.py 2013-07-28 18:32:55.591158774 +0100 ++++ /tmp/pylint_iHIz1e/__init__.py 2013-07-28 18:33:03.527198125 +0100 +@@ -1,5 +1,5 @@ + from .http import Http +-from .errors import * ++from .errors import * # pylint: disable=W0401 + from ._version import __version__ + from . import api_photo + from . import api_tag +@@ -19,7 +19,7 @@ + This should be used to ensure that your application will continue to work + even if the Trovebox API is updated to a new revision. + """ +- def __init__(self, config_file=None, host=None, ++ def __init__(self, config_file=None, host=None, # pylint: disable=R0913 + consumer_key='', consumer_secret='', + token='', token_secret='', + api_version=None): +diff --unified --recursive '--exclude=.pylint-ignores.patch' ./main.py /tmp/pylint_iHIz1e/main.py +--- ./main.py 2013-07-28 18:32:55.591158774 +0100 ++++ /tmp/pylint_iHIz1e/main.py 2013-07-28 18:32:52.787144864 +0100 +@@ -23,7 +23,7 @@ + + ################################################################# + +-def main(args=sys.argv[1:]): ++def main(args=sys.argv[1:]): # pylint: disable=R0912,C0111 + usage = "%prog --help" + parser = OptionParser(usage, add_help_option=False) + parser.add_option('-c', '--config', help="Configuration file to use", +@@ -81,13 +81,13 @@ + sys.exit(1) + + if options.method == "GET": +- result = client.get(options.endpoint, process_response=False, ++ result = client.get(options.endpoint, process_response=False, # pylint: disable=W0142 + **params) + else: + params, files = extract_files(params) +- result = client.post(options.endpoint, process_response=False, ++ result = client.post(options.endpoint, process_response=False, # pylint: disable=W0142 + files=files, **params) +- for f in files: ++ for f in files: # pylint: disable=C0103 + files[f].close() + + if options.verbose: +diff --unified --recursive '--exclude=.pylint-ignores.patch' ./objects.py /tmp/pylint_iHIz1e/objects.py +--- ./objects.py 2013-07-28 18:32:55.591158774 +0100 ++++ /tmp/pylint_iHIz1e/objects.py 2013-07-28 18:32:52.787144864 +0100 +@@ -1,14 +1,14 @@ + try: +- from urllib.parse import quote # Python3 ++ from urllib.parse import quote # Python3 # pylint: disable=F0401,E0611 + except ImportError: + from urllib import quote # Python2 + + from .errors import TroveboxError + +-class TroveboxObject(object): ++class TroveboxObject(object): # pylint: disable=R0903 + """ Base object supporting the storage of custom fields as attributes """ + def __init__(self, trovebox, json_dict): +- self.id = None ++ self.id = None # pylint: disable=C0103 + self.name = None + self._trovebox = trovebox + self._json_dict = json_dict +@@ -54,7 +54,7 @@ + return self._json_dict + + +-class Photo(TroveboxObject): ++class Photo(TroveboxObject): # pylint: disable=C0111 + def delete(self, **kwds): + """ + Delete this photo. +@@ -144,7 +144,7 @@ + + self._replace_fields(new_dict) + +-class Tag(TroveboxObject): ++class Tag(TroveboxObject): # pylint: disable=C0111 + def delete(self, **kwds): + """ + Delete this tag. +@@ -165,7 +165,7 @@ + self._replace_fields(new_dict) + + +-class Album(TroveboxObject): ++class Album(TroveboxObject): # pylint: disable=C0111 + def __init__(self, trovebox, json_dict): + self.photos = None + self.cover = None diff --git a/trovebox/api_album.py b/trovebox/api_album.py index 9c212c0..79dfe29 100644 --- a/trovebox/api_album.py +++ b/trovebox/api_album.py @@ -1,6 +1,6 @@ from .objects import Album -class ApiAlbums: +class ApiAlbums(object): def __init__(self, client): self._client = client @@ -9,7 +9,7 @@ class ApiAlbums: results = self._client.get("/albums/list.json", **kwds)["result"] return [Album(self._client, album) for album in results] -class ApiAlbum: +class ApiAlbum(object): def __init__(self, client): self._client = client @@ -30,12 +30,15 @@ class ApiAlbum: return album.delete(**kwds) def form(self, album, **kwds): + """ Not yet implemented """ raise NotImplementedError() def add_photos(self, album, photos, **kwds): + """ Not yet implemented """ raise NotImplementedError() def remove_photos(self, album, photos, **kwds): + """ Not yet implemented """ raise NotImplementedError() def update(self, album, **kwds): diff --git a/trovebox/api_photo.py b/trovebox/api_photo.py index 6c1eacf..75783df 100644 --- a/trovebox/api_photo.py +++ b/trovebox/api_photo.py @@ -17,7 +17,7 @@ def extract_ids(photos): ids.append(photo) return ids -class ApiPhotos: +class ApiPhotos(object): def __init__(self, client): self._client = client @@ -51,7 +51,7 @@ class ApiPhotos: raise TroveboxError("Delete response returned False") return True -class ApiPhoto: +class ApiPhoto(object): def __init__(self, client): self._client = client @@ -72,9 +72,11 @@ class ApiPhoto: return photo.edit(**kwds) def replace(self, photo, photo_file, **kwds): + """ Not yet implemented """ raise NotImplementedError() def replace_encoded(self, photo, photo_file, **kwds): + """ Not yet implemented """ raise NotImplementedError() def update(self, photo, **kwds): @@ -114,6 +116,7 @@ class ApiPhoto: return Photo(self._client, result) def dynamic_url(self, photo, **kwds): + """ Not yet implemented """ raise NotImplementedError() def next_previous(self, photo, **kwds): diff --git a/trovebox/api_tag.py b/trovebox/api_tag.py index 4221c9a..d80a9d1 100644 --- a/trovebox/api_tag.py +++ b/trovebox/api_tag.py @@ -1,6 +1,6 @@ from .objects import Tag -class ApiTags: +class ApiTags(object): def __init__(self, client): self._client = client @@ -9,7 +9,7 @@ class ApiTags: results = self._client.get("/tags/list.json", **kwds)["result"] return [Tag(self._client, tag) for tag in results] -class ApiTag: +class ApiTag(object): def __init__(self, client): self._client = client diff --git a/trovebox/config.py b/trovebox/config.py index bacef2b..e18f30b 100644 --- a/trovebox/config.py +++ b/trovebox/config.py @@ -9,7 +9,7 @@ try: except ImportError: import StringIO as io # Python2 -class Config: +class Config(object): def __init__(self, config_file, host, consumer_key, consumer_secret, token, token_secret): @@ -46,7 +46,8 @@ def get_config_path(config_file): def read_config(config_path): """ Loads config data from the specified file path. - If config_file doesn't exist, returns an empty authentication config for localhost. + If config_file doesn't exist, returns an empty authentication config + for localhost. """ section = "DUMMY" defaults = {'host': 'localhost', diff --git a/trovebox/http.py b/trovebox/http.py index fef1fdc..6d45d31 100644 --- a/trovebox/http.py +++ b/trovebox/http.py @@ -20,7 +20,7 @@ else: DUPLICATE_RESPONSE = {"code": 409, "message": "This photo already exists"} -class Http: +class Http(object): """ Base class to handle HTTP requests to an Trovebox server. If no parameters are specified, config is loaded from the default diff --git a/trovebox/main.py b/trovebox/main.py index dfe2573..7472bc6 100644 --- a/trovebox/main.py +++ b/trovebox/main.py @@ -44,7 +44,7 @@ def main(args=sys.argv[1:]): action="store_true", dest="pretty", default=False) parser.add_option('-v', help="Verbose output", action="store_true", dest="verbose", default=False) - parser.add_option('--version', help="Display the current version information", + parser.add_option('--version', help="Display the current version", action="store_true") parser.add_option('--help', help='show this help message', action="store_true") @@ -107,7 +107,8 @@ def main(args=sys.argv[1:]): def extract_files(params): """ - Extract filenames from the "photo" parameter, so they can be uploaded, returning (updated_params, files). + Extract filenames from the "photo" parameter so they can be uploaded, + returning (updated_params, files). Uses the same technique as the Trovebox PHP commandline tool: * Filename can only be in the "photo" parameter * Filename must be prefixed with "@" diff --git a/trovebox/objects.py b/trovebox/objects.py index ffced54..805983f 100644 --- a/trovebox/objects.py +++ b/trovebox/objects.py @@ -5,7 +5,7 @@ except ImportError: from .errors import TroveboxError -class TroveboxObject: +class TroveboxObject(object): """ Base object supporting the storage of custom fields as attributes """ def __init__(self, trovebox, json_dict): self.id = None @@ -75,9 +75,11 @@ class Photo(TroveboxObject): return result["markup"] def replace(self, photo_file, **kwds): + """ Not implemented yet """ raise NotImplementedError() def replace_encoded(self, photo_file, **kwds): + """ Not implemented yet """ raise NotImplementedError() def update(self, **kwds): @@ -96,6 +98,7 @@ class Photo(TroveboxObject): self._replace_fields(new_dict) def dynamic_url(self, **kwds): + """ Not implemented yet """ raise NotImplementedError() def next_previous(self, **kwds): @@ -194,12 +197,15 @@ class Album(TroveboxObject): return result def form(self, **kwds): + """ Not implemented yet """ raise NotImplementedError() def add_photos(self, photos, **kwds): + """ Not implemented yet """ raise NotImplementedError() def remove_photos(self, photos, **kwds): + """ Not implemented yet """ raise NotImplementedError() def update(self, **kwds): From 5cce9482db5f99fe866ecbfbe218a6c1c9870a8f Mon Sep 17 00:00:00 2001 From: sneakypete81 Date: Sun, 28 Jul 2013 19:36:41 +0100 Subject: [PATCH 02/19] Pylint ignores --- trovebox/.pylint-ignores.patch | 119 +++++++++++++++++++++------------ 1 file changed, 76 insertions(+), 43 deletions(-) diff --git a/trovebox/.pylint-ignores.patch b/trovebox/.pylint-ignores.patch index 26a95cb..7870ebd 100644 --- a/trovebox/.pylint-ignores.patch +++ b/trovebox/.pylint-ignores.patch @@ -1,7 +1,8 @@ -diff --unified --recursive '--exclude=.pylint-ignores.patch' ./api_album.py /tmp/pylint_iHIz1e/api_album.py ---- ./api_album.py 2013-07-28 18:32:55.587158750 +0100 -+++ /tmp/pylint_iHIz1e/api_album.py 2013-07-28 18:32:52.783144848 +0100 -@@ -1,6 +1,6 @@ +diff --unified --recursive '--exclude=.pylint-ignores.patch' ./api_album.py /tmp/pylint_zL0Fvx/api_album.py +--- ./api_album.py 2013-07-28 19:34:26.921934852 +0100 ++++ /tmp/pylint_zL0Fvx/api_album.py 2013-07-28 19:34:32.149960776 +0100 +@@ -1,6 +1,7 @@ ++ # pylint: disable=C0111 from .objects import Album -class ApiAlbums(object): @@ -9,7 +10,7 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' ./api_album.py /tmp def __init__(self, client): self._client = client -@@ -9,7 +9,7 @@ +@@ -9,7 +10,7 @@ results = self._client.get("/albums/list.json", **kwds)["result"] return [Album(self._client, album) for album in results] @@ -18,10 +19,15 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' ./api_album.py /tmp def __init__(self, client): self._client = client -diff --unified --recursive '--exclude=.pylint-ignores.patch' ./api_photo.py /tmp/pylint_iHIz1e/api_photo.py ---- ./api_photo.py 2013-07-28 18:32:55.587158750 +0100 -+++ /tmp/pylint_iHIz1e/api_photo.py 2013-07-28 18:32:52.787144864 +0100 -@@ -17,7 +17,7 @@ +diff --unified --recursive '--exclude=.pylint-ignores.patch' ./api_photo.py /tmp/pylint_zL0Fvx/api_photo.py +--- ./api_photo.py 2013-07-28 19:34:26.921934852 +0100 ++++ /tmp/pylint_zL0Fvx/api_photo.py 2013-07-28 19:34:33.981969860 +0100 +@@ -1,3 +1,4 @@ ++ # pylint: disable=C0111 + import base64 + + from .errors import TroveboxError +@@ -17,7 +18,7 @@ ids.append(photo) return ids @@ -30,7 +36,7 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' ./api_photo.py /tmp def __init__(self, client): self._client = client -@@ -51,7 +51,7 @@ +@@ -51,7 +52,7 @@ raise TroveboxError("Delete response returned False") return True @@ -39,10 +45,11 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' ./api_photo.py /tmp def __init__(self, client): self._client = client -diff --unified --recursive '--exclude=.pylint-ignores.patch' ./api_tag.py /tmp/pylint_iHIz1e/api_tag.py ---- ./api_tag.py 2013-07-28 18:32:55.587158750 +0100 -+++ /tmp/pylint_iHIz1e/api_tag.py 2013-07-28 18:32:52.787144864 +0100 -@@ -1,6 +1,6 @@ +diff --unified --recursive '--exclude=.pylint-ignores.patch' ./api_tag.py /tmp/pylint_zL0Fvx/api_tag.py +--- ./api_tag.py 2013-07-28 19:34:26.925934871 +0100 ++++ /tmp/pylint_zL0Fvx/api_tag.py 2013-07-28 19:34:45.134025160 +0100 +@@ -1,6 +1,7 @@ ++ # pylint: disable=C0111 from .objects import Tag -class ApiTags(object): @@ -50,7 +57,7 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' ./api_tag.py /tmp/p def __init__(self, client): self._client = client -@@ -9,7 +9,7 @@ +@@ -9,7 +10,7 @@ results = self._client.get("/tags/list.json", **kwds)["result"] return [Tag(self._client, tag) for tag in results] @@ -59,10 +66,11 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' ./api_tag.py /tmp/p def __init__(self, client): self._client = client -diff --unified --recursive '--exclude=.pylint-ignores.patch' ./config.py /tmp/pylint_iHIz1e/config.py ---- ./config.py 2013-07-28 18:32:55.587158750 +0100 -+++ /tmp/pylint_iHIz1e/config.py 2013-07-28 18:32:52.787144864 +0100 -@@ -1,7 +1,7 @@ +diff --unified --recursive '--exclude=.pylint-ignores.patch' ./config.py /tmp/pylint_zL0Fvx/config.py +--- ./config.py 2013-07-28 19:34:26.925934871 +0100 ++++ /tmp/pylint_zL0Fvx/config.py 2013-07-28 19:34:40.522002291 +0100 +@@ -1,7 +1,8 @@ ++ # pylint: disable=C0111 from __future__ import unicode_literals import os try: @@ -71,7 +79,7 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' ./config.py /tmp/py except ImportError: from ConfigParser import SafeConfigParser as ConfigParser # Python2 try: -@@ -9,8 +9,8 @@ +@@ -9,8 +10,8 @@ except ImportError: import StringIO as io # Python2 @@ -82,7 +90,7 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' ./config.py /tmp/py consumer_key, consumer_secret, token, token_secret): if host is None: -@@ -65,7 +65,7 @@ +@@ -65,7 +66,7 @@ parser = ConfigParser() parser.optionxform = str # Case-sensitive options try: @@ -91,10 +99,22 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' ./config.py /tmp/py except AttributeError: parser.readfp(buf) # Python2 -diff --unified --recursive '--exclude=.pylint-ignores.patch' ./http.py /tmp/pylint_iHIz1e/http.py ---- ./http.py 2013-07-28 18:32:55.591158774 +0100 -+++ /tmp/pylint_iHIz1e/http.py 2013-07-28 18:32:52.787144864 +0100 -@@ -4,18 +4,18 @@ +diff --unified --recursive '--exclude=.pylint-ignores.patch' ./errors.py /tmp/pylint_zL0Fvx/errors.py +--- ./errors.py 2013-07-28 19:30:27.132745801 +0100 ++++ /tmp/pylint_zL0Fvx/errors.py 2013-07-28 19:34:41.930009273 +0100 +@@ -1,3 +1,4 @@ ++ # pylint: disable=C0111 + class TroveboxError(Exception): + """ Indicates that an Trovebox operation failed """ + pass +diff --unified --recursive '--exclude=.pylint-ignores.patch' ./http.py /tmp/pylint_zL0Fvx/http.py +--- ./http.py 2013-07-28 19:34:26.925934871 +0100 ++++ /tmp/pylint_zL0Fvx/http.py 2013-07-28 19:34:36.453982118 +0100 +@@ -1,21 +1,22 @@ ++ # pylint: disable=C0111 + from __future__ import unicode_literals + import sys + import requests import requests_oauthlib import logging try: @@ -117,7 +137,7 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' ./http.py /tmp/pyli DUPLICATE_RESPONSE = {"code": 409, "message": "This photo already exists"} -@@ -32,7 +32,7 @@ +@@ -32,7 +33,7 @@ This should be used to ensure that your application will continue to work even if the Trovebox API is updated to a new revision. """ @@ -126,17 +146,18 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' ./http.py /tmp/pyli consumer_key='', consumer_secret='', token='', token_secret='', api_version=None): self._api_version = api_version -diff --unified --recursive '--exclude=.pylint-ignores.patch' ./__init__.py /tmp/pylint_iHIz1e/__init__.py ---- ./__init__.py 2013-07-28 18:32:55.591158774 +0100 -+++ /tmp/pylint_iHIz1e/__init__.py 2013-07-28 18:33:03.527198125 +0100 -@@ -1,5 +1,5 @@ +diff --unified --recursive '--exclude=.pylint-ignores.patch' ./__init__.py /tmp/pylint_zL0Fvx/__init__.py +--- ./__init__.py 2013-07-28 19:34:26.925934871 +0100 ++++ /tmp/pylint_zL0Fvx/__init__.py 2013-07-28 19:34:28.705943698 +0100 +@@ -1,5 +1,6 @@ ++ # pylint: disable=C0111 from .http import Http -from .errors import * +from .errors import * # pylint: disable=W0401 from ._version import __version__ from . import api_photo from . import api_tag -@@ -19,7 +19,7 @@ +@@ -19,7 +20,7 @@ This should be used to ensure that your application will continue to work even if the Trovebox API is updated to a new revision. """ @@ -145,10 +166,15 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' ./__init__.py /tmp/ consumer_key='', consumer_secret='', token='', token_secret='', api_version=None): -diff --unified --recursive '--exclude=.pylint-ignores.patch' ./main.py /tmp/pylint_iHIz1e/main.py ---- ./main.py 2013-07-28 18:32:55.591158774 +0100 -+++ /tmp/pylint_iHIz1e/main.py 2013-07-28 18:32:52.787144864 +0100 -@@ -23,7 +23,7 @@ +diff --unified --recursive '--exclude=.pylint-ignores.patch' ./main.py /tmp/pylint_zL0Fvx/main.py +--- ./main.py 2013-07-28 19:34:26.925934871 +0100 ++++ /tmp/pylint_zL0Fvx/main.py 2013-07-28 19:34:30.345951830 +0100 +@@ -1,3 +1,4 @@ ++ # pylint: disable=C0111 + #!/usr/bin/env python + import os + import sys +@@ -23,7 +24,7 @@ ################################################################# @@ -157,7 +183,7 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' ./main.py /tmp/pyli usage = "%prog --help" parser = OptionParser(usage, add_help_option=False) parser.add_option('-c', '--config', help="Configuration file to use", -@@ -81,13 +81,13 @@ +@@ -81,13 +82,13 @@ sys.exit(1) if options.method == "GET": @@ -174,10 +200,11 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' ./main.py /tmp/pyli files[f].close() if options.verbose: -diff --unified --recursive '--exclude=.pylint-ignores.patch' ./objects.py /tmp/pylint_iHIz1e/objects.py ---- ./objects.py 2013-07-28 18:32:55.591158774 +0100 -+++ /tmp/pylint_iHIz1e/objects.py 2013-07-28 18:32:52.787144864 +0100 -@@ -1,14 +1,14 @@ +diff --unified --recursive '--exclude=.pylint-ignores.patch' ./objects.py /tmp/pylint_zL0Fvx/objects.py +--- ./objects.py 2013-07-28 19:34:26.925934871 +0100 ++++ /tmp/pylint_zL0Fvx/objects.py 2013-07-28 19:34:38.969994595 +0100 +@@ -1,14 +1,15 @@ ++ # pylint: disable=C0111 try: - from urllib.parse import quote # Python3 + from urllib.parse import quote # Python3 # pylint: disable=F0401,E0611 @@ -195,7 +222,7 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' ./objects.py /tmp/p self.name = None self._trovebox = trovebox self._json_dict = json_dict -@@ -54,7 +54,7 @@ +@@ -54,7 +55,7 @@ return self._json_dict @@ -204,7 +231,7 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' ./objects.py /tmp/p def delete(self, **kwds): """ Delete this photo. -@@ -144,7 +144,7 @@ +@@ -144,7 +145,7 @@ self._replace_fields(new_dict) @@ -213,7 +240,7 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' ./objects.py /tmp/p def delete(self, **kwds): """ Delete this tag. -@@ -165,7 +165,7 @@ +@@ -165,7 +166,7 @@ self._replace_fields(new_dict) @@ -222,3 +249,9 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' ./objects.py /tmp/p def __init__(self, trovebox, json_dict): self.photos = None self.cover = None +diff --unified --recursive '--exclude=.pylint-ignores.patch' ./_version.py /tmp/pylint_zL0Fvx/_version.py +--- ./_version.py 2013-07-28 19:30:27.132745801 +0100 ++++ /tmp/pylint_zL0Fvx/_version.py 2013-07-28 19:34:43.226015699 +0100 +@@ -1 +1,2 @@ ++ # pylint: disable=C0111 + __version__ = "0.4" From a3d492460e4a0bd167d1e67da4977b73d70bdc6a Mon Sep 17 00:00:00 2001 From: sneakypete81 Date: Tue, 30 Jul 2013 17:59:16 +0100 Subject: [PATCH 03/19] Rename openphoto->trovebox --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index e8f456e..1faf6a6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,6 +9,5 @@ script: tox after_script: # Run Pylint # (for information only, any errors don't affect the Travis result) - - pylint --use-ignore-patch=y openphoto + - pylint --use-ignore-patch=y trovebox - pylint --use-ignore-patch=y tests - From 4b2039b661ae6f36ed4dc1d2918366feb28bf56b Mon Sep 17 00:00:00 2001 From: sneakypete81 Date: Tue, 30 Jul 2013 17:59:44 +0100 Subject: [PATCH 04/19] Always get the latest use_ignore_patch PR for Pylint --- .travis/install_pylint | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.travis/install_pylint b/.travis/install_pylint index e3ea6c2..873c011 100755 --- a/.travis/install_pylint +++ b/.travis/install_pylint @@ -1,11 +1,10 @@ # Until the --use-ignore-patch makes it into pylint upstream, we need to # download and install from sneakypete81's pylint fork -HG_HASH=16de8b9518be -wget https://bitbucket.org/sneakypete81/pylint/get/$HG_HASH.zip +wget https://bitbucket.org/sneakypete81/pylint/get/use_ignore_patch.zip unzip $HG_HASH.zip -cd sneakypete81-pylint-$HG_HASH +cd sneakypete81-pylint-* python setup.py install cd .. -rm -r sneakypete81-pylint-$HG_HASH +rm -r sneakypete81-pylint-* From 21d70a90b170e01336eaae8581e57e999880f9b8 Mon Sep 17 00:00:00 2001 From: sneakypete81 Date: Tue, 30 Jul 2013 19:21:41 +0100 Subject: [PATCH 05/19] Fix unzip filename --- .travis/install_pylint | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis/install_pylint b/.travis/install_pylint index 873c011..0f5ce45 100755 --- a/.travis/install_pylint +++ b/.travis/install_pylint @@ -2,7 +2,7 @@ # download and install from sneakypete81's pylint fork wget https://bitbucket.org/sneakypete81/pylint/get/use_ignore_patch.zip -unzip $HG_HASH.zip +unzip use_ignore_patch.zip cd sneakypete81-pylint-* python setup.py install From 384bc75c015566d530796b9f12ba968b4b766006 Mon Sep 17 00:00:00 2001 From: sneakypete81 Date: Wed, 7 Aug 2013 21:28:00 +0100 Subject: [PATCH 06/19] Update to new pylint patchfile format --- trovebox/.pylint-ignores.patch | 87 ++++++++++++---------------------- 1 file changed, 30 insertions(+), 57 deletions(-) diff --git a/trovebox/.pylint-ignores.patch b/trovebox/.pylint-ignores.patch index 7870ebd..0ef022d 100644 --- a/trovebox/.pylint-ignores.patch +++ b/trovebox/.pylint-ignores.patch @@ -1,6 +1,6 @@ -diff --unified --recursive '--exclude=.pylint-ignores.patch' ./api_album.py /tmp/pylint_zL0Fvx/api_album.py ---- ./api_album.py 2013-07-28 19:34:26.921934852 +0100 -+++ /tmp/pylint_zL0Fvx/api_album.py 2013-07-28 19:34:32.149960776 +0100 +diff --unified --recursive '--exclude=.pylint-ignores.patch' original/api_album.py patched/api_album.py +--- original/api_album.py 2013-08-07 21:13:32.151830000 +0100 ++++ patched/api_album.py 2013-08-07 21:13:59.879967978 +0100 @@ -1,6 +1,7 @@ + # pylint: disable=C0111 from .objects import Album @@ -19,9 +19,9 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' ./api_album.py /tmp def __init__(self, client): self._client = client -diff --unified --recursive '--exclude=.pylint-ignores.patch' ./api_photo.py /tmp/pylint_zL0Fvx/api_photo.py ---- ./api_photo.py 2013-07-28 19:34:26.921934852 +0100 -+++ /tmp/pylint_zL0Fvx/api_photo.py 2013-07-28 19:34:33.981969860 +0100 +diff --unified --recursive '--exclude=.pylint-ignores.patch' original/api_photo.py patched/api_photo.py +--- original/api_photo.py 2013-08-07 21:13:32.151830000 +0100 ++++ patched/api_photo.py 2013-08-07 21:13:59.879967978 +0100 @@ -1,3 +1,4 @@ + # pylint: disable=C0111 import base64 @@ -45,9 +45,9 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' ./api_photo.py /tmp def __init__(self, client): self._client = client -diff --unified --recursive '--exclude=.pylint-ignores.patch' ./api_tag.py /tmp/pylint_zL0Fvx/api_tag.py ---- ./api_tag.py 2013-07-28 19:34:26.925934871 +0100 -+++ /tmp/pylint_zL0Fvx/api_tag.py 2013-07-28 19:34:45.134025160 +0100 +diff --unified --recursive '--exclude=.pylint-ignores.patch' original/api_tag.py patched/api_tag.py +--- original/api_tag.py 2013-08-07 21:13:32.151830000 +0100 ++++ patched/api_tag.py 2013-08-07 21:13:59.879967978 +0100 @@ -1,6 +1,7 @@ + # pylint: disable=C0111 from .objects import Tag @@ -66,9 +66,9 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' ./api_tag.py /tmp/p def __init__(self, client): self._client = client -diff --unified --recursive '--exclude=.pylint-ignores.patch' ./config.py /tmp/pylint_zL0Fvx/config.py ---- ./config.py 2013-07-28 19:34:26.925934871 +0100 -+++ /tmp/pylint_zL0Fvx/config.py 2013-07-28 19:34:40.522002291 +0100 +diff --unified --recursive '--exclude=.pylint-ignores.patch' original/config.py patched/config.py +--- original/config.py 2013-08-07 21:13:32.151830000 +0100 ++++ patched/config.py 2013-08-07 21:13:59.879967978 +0100 @@ -1,7 +1,8 @@ + # pylint: disable=C0111 from __future__ import unicode_literals @@ -99,17 +99,17 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' ./config.py /tmp/py except AttributeError: parser.readfp(buf) # Python2 -diff --unified --recursive '--exclude=.pylint-ignores.patch' ./errors.py /tmp/pylint_zL0Fvx/errors.py ---- ./errors.py 2013-07-28 19:30:27.132745801 +0100 -+++ /tmp/pylint_zL0Fvx/errors.py 2013-07-28 19:34:41.930009273 +0100 +diff --unified --recursive '--exclude=.pylint-ignores.patch' original/errors.py patched/errors.py +--- original/errors.py 2013-08-07 21:13:32.151830000 +0100 ++++ patched/errors.py 2013-08-07 21:13:59.879967978 +0100 @@ -1,3 +1,4 @@ + # pylint: disable=C0111 class TroveboxError(Exception): """ Indicates that an Trovebox operation failed """ pass -diff --unified --recursive '--exclude=.pylint-ignores.patch' ./http.py /tmp/pylint_zL0Fvx/http.py ---- ./http.py 2013-07-28 19:34:26.925934871 +0100 -+++ /tmp/pylint_zL0Fvx/http.py 2013-07-28 19:34:36.453982118 +0100 +diff --unified --recursive '--exclude=.pylint-ignores.patch' original/http.py patched/http.py +--- original/http.py 2013-08-07 21:13:32.151830000 +0100 ++++ patched/http.py 2013-08-07 21:13:59.879967978 +0100 @@ -1,21 +1,22 @@ + # pylint: disable=C0111 from __future__ import unicode_literals @@ -146,9 +146,9 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' ./http.py /tmp/pyli consumer_key='', consumer_secret='', token='', token_secret='', api_version=None): self._api_version = api_version -diff --unified --recursive '--exclude=.pylint-ignores.patch' ./__init__.py /tmp/pylint_zL0Fvx/__init__.py ---- ./__init__.py 2013-07-28 19:34:26.925934871 +0100 -+++ /tmp/pylint_zL0Fvx/__init__.py 2013-07-28 19:34:28.705943698 +0100 +diff --unified --recursive '--exclude=.pylint-ignores.patch' original/__init__.py patched/__init__.py +--- original/__init__.py 2013-08-07 21:13:32.151830000 +0100 ++++ patched/__init__.py 2013-08-07 21:13:59.879967978 +0100 @@ -1,5 +1,6 @@ + # pylint: disable=C0111 from .http import Http @@ -166,9 +166,9 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' ./__init__.py /tmp/ consumer_key='', consumer_secret='', token='', token_secret='', api_version=None): -diff --unified --recursive '--exclude=.pylint-ignores.patch' ./main.py /tmp/pylint_zL0Fvx/main.py ---- ./main.py 2013-07-28 19:34:26.925934871 +0100 -+++ /tmp/pylint_zL0Fvx/main.py 2013-07-28 19:34:30.345951830 +0100 +diff --unified --recursive '--exclude=.pylint-ignores.patch' original/main.py patched/main.py +--- original/main.py 2013-08-07 21:13:32.151830000 +0100 ++++ patched/main.py 2013-08-07 21:13:59.883967994 +0100 @@ -1,3 +1,4 @@ + # pylint: disable=C0111 #!/usr/bin/env python @@ -200,9 +200,9 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' ./main.py /tmp/pyli files[f].close() if options.verbose: -diff --unified --recursive '--exclude=.pylint-ignores.patch' ./objects.py /tmp/pylint_zL0Fvx/objects.py ---- ./objects.py 2013-07-28 19:34:26.925934871 +0100 -+++ /tmp/pylint_zL0Fvx/objects.py 2013-07-28 19:34:38.969994595 +0100 +diff --unified --recursive '--exclude=.pylint-ignores.patch' original/objects.py patched/objects.py +--- original/objects.py 2013-08-07 21:13:32.155830000 +0100 ++++ patched/objects.py 2013-08-07 21:13:59.883967994 +0100 @@ -1,14 +1,15 @@ + # pylint: disable=C0111 try: @@ -222,36 +222,9 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' ./objects.py /tmp/p self.name = None self._trovebox = trovebox self._json_dict = json_dict -@@ -54,7 +55,7 @@ - return self._json_dict - - --class Photo(TroveboxObject): -+class Photo(TroveboxObject): # pylint: disable=C0111 - def delete(self, **kwds): - """ - Delete this photo. -@@ -144,7 +145,7 @@ - - self._replace_fields(new_dict) - --class Tag(TroveboxObject): -+class Tag(TroveboxObject): # pylint: disable=C0111 - def delete(self, **kwds): - """ - Delete this tag. -@@ -165,7 +166,7 @@ - self._replace_fields(new_dict) - - --class Album(TroveboxObject): -+class Album(TroveboxObject): # pylint: disable=C0111 - def __init__(self, trovebox, json_dict): - self.photos = None - self.cover = None -diff --unified --recursive '--exclude=.pylint-ignores.patch' ./_version.py /tmp/pylint_zL0Fvx/_version.py ---- ./_version.py 2013-07-28 19:30:27.132745801 +0100 -+++ /tmp/pylint_zL0Fvx/_version.py 2013-07-28 19:34:43.226015699 +0100 +diff --unified --recursive '--exclude=.pylint-ignores.patch' original/_version.py patched/_version.py +--- original/_version.py 2013-08-07 21:12:22.487484000 +0100 ++++ patched/_version.py 2013-08-07 21:14:05.947998060 +0100 @@ -1 +1,2 @@ + # pylint: disable=C0111 __version__ = "0.4" From 42b2eac326c4ba89fe994ba1413223cbd3e58597 Mon Sep 17 00:00:00 2001 From: sneakypete81 Date: Wed, 7 Aug 2013 21:38:53 +0100 Subject: [PATCH 07/19] Don't run PyLint on the tests --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 1faf6a6..bcf266c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,4 +10,3 @@ after_script: # Run Pylint # (for information only, any errors don't affect the Travis result) - pylint --use-ignore-patch=y trovebox - - pylint --use-ignore-patch=y tests From 1a2722b34b1bf8d468c5272bf5fb8c6edb6e5675 Mon Sep 17 00:00:00 2001 From: sneakypete81 Date: Wed, 7 Aug 2013 21:47:04 +0100 Subject: [PATCH 08/19] Install dependencies before running PyLint --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index bcf266c..6891aed 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,9 @@ install: script: tox after_script: + # Install dependencies for Pylint + - pip install requests requests-oauthlib + # Run Pylint # (for information only, any errors don't affect the Travis result) - pylint --use-ignore-patch=y trovebox From d61e6ec4897c3de47e5658294cdec5f9e020ecf7 Mon Sep 17 00:00:00 2001 From: sneakypete81 Date: Wed, 7 Aug 2013 21:51:40 +0100 Subject: [PATCH 09/19] Only show TravisCI badge for the Master branch Previously it reported the latest build from any branch --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index e66dba1..9c5125a 100644 --- a/README.rst +++ b/README.rst @@ -3,7 +3,7 @@ Trovebox Python Library ======================= (Previously known as openphoto-python) -.. image:: https://api.travis-ci.org/photo/openphoto-python.png +.. image:: https://travis-ci.org/photo/openphoto-python.png?branch=master :alt: Build Status :target: https://travis-ci.org/photo/openphoto-python From 9a2c3e0d975f4b3f29ca121f1e56ac67fece0902 Mon Sep 17 00:00:00 2001 From: Pete Date: Mon, 12 Aug 2013 17:31:07 +0100 Subject: [PATCH 10/19] Added support for https URLs. Fixes #51. --- tests/unit/test_http.py | 90 ++++++++++++++++++++++++++++++++++ trovebox/.pylint-ignores.patch | 54 ++++++++++---------- trovebox/http.py | 32 +++++++----- 3 files changed, 135 insertions(+), 41 deletions(-) diff --git a/tests/unit/test_http.py b/tests/unit/test_http.py index 8f5ac3e..9235453 100644 --- a/tests/unit/test_http.py +++ b/tests/unit/test_http.py @@ -46,6 +46,96 @@ class TestHttp(unittest.TestCase): self.assertEqual(self.client.host, self.test_host) self.assertEqual(self.client.config.host, self.test_host) + @httpretty.activate + def test_get_with_http_scheme(self): + """Check that the get method works with a host starting with 'http://'""" + self._register_uri(httpretty.GET, + uri="http://test.example.com/%s" % self.test_endpoint) + + self.client = trovebox.Trovebox(host="http://test.example.com", + **self.test_oauth) + response = self.client.get(self.test_endpoint) + self.assertIn("OAuth", self._last_request().headers["authorization"]) + self.assertEqual(response, self.test_data) + self.assertEqual(self.client.last_url, + "http://test.example.com/%s" % self.test_endpoint) + self.assertEqual(self.client.last_response.json(), self.test_data) + + @httpretty.activate + def test_get_with_no_scheme(self): + """Check that the get method works with a host without a 'http://' prefix""" + self._register_uri(httpretty.GET, + uri="http://test.example.com/%s" % self.test_endpoint) + + self.client = trovebox.Trovebox(host="test.example.com", + **self.test_oauth) + response = self.client.get(self.test_endpoint) + self.assertIn("OAuth", self._last_request().headers["authorization"]) + self.assertEqual(response, self.test_data) + self.assertEqual(self.client.last_url, + "http://test.example.com/%s" % self.test_endpoint) + self.assertEqual(self.client.last_response.json(), self.test_data) + + @httpretty.activate + def test_get_with_https_scheme(self): + """Check that the get method works with a host starting with 'https://'""" + self._register_uri(httpretty.GET, + uri="https://test.example.com/%s" % self.test_endpoint) + + self.client = trovebox.Trovebox(host="https://test.example.com", + **self.test_oauth) + response = self.client.get(self.test_endpoint) + self.assertIn("OAuth", self._last_request().headers["authorization"]) + self.assertEqual(response, self.test_data) + self.assertEqual(self.client.last_url, + "https://test.example.com/%s" % self.test_endpoint) + self.assertEqual(self.client.last_response.json(), self.test_data) + + @httpretty.activate + def test_post_with_http_scheme(self): + """Check that the post method works with a host starting with 'http://'""" + self._register_uri(httpretty.POST, + uri="http://test.example.com/%s" % self.test_endpoint) + + self.client = trovebox.Trovebox(host="http://test.example.com", + **self.test_oauth) + response = self.client.post(self.test_endpoint) + self.assertIn("OAuth", self._last_request().headers["authorization"]) + self.assertEqual(response, self.test_data) + self.assertEqual(self.client.last_url, + "http://test.example.com/%s" % self.test_endpoint) + self.assertEqual(self.client.last_response.json(), self.test_data) + + @httpretty.activate + def test_post_with_no_scheme(self): + """Check that the post method works with a host without a 'http://' prefix""" + self._register_uri(httpretty.POST, + uri="http://test.example.com/%s" % self.test_endpoint) + + self.client = trovebox.Trovebox(host="test.example.com", + **self.test_oauth) + response = self.client.post(self.test_endpoint) + self.assertIn("OAuth", self._last_request().headers["authorization"]) + self.assertEqual(response, self.test_data) + self.assertEqual(self.client.last_url, + "http://test.example.com/%s" % self.test_endpoint) + self.assertEqual(self.client.last_response.json(), self.test_data) + + @httpretty.activate + def test_post_with_https_scheme(self): + """Check that the post method works with a host starting with 'https://'""" + self._register_uri(httpretty.POST, + uri="https://test.example.com/%s" % self.test_endpoint) + + self.client = trovebox.Trovebox(host="https://test.example.com", + **self.test_oauth) + response = self.client.post(self.test_endpoint) + self.assertIn("OAuth", self._last_request().headers["authorization"]) + self.assertEqual(response, self.test_data) + self.assertEqual(self.client.last_url, + "https://test.example.com/%s" % self.test_endpoint) + self.assertEqual(self.client.last_response.json(), self.test_data) + @httpretty.activate def test_get_with_parameters(self): """Check that the get method accepts parameters correctly""" diff --git a/trovebox/.pylint-ignores.patch b/trovebox/.pylint-ignores.patch index 0ef022d..52deaf8 100644 --- a/trovebox/.pylint-ignores.patch +++ b/trovebox/.pylint-ignores.patch @@ -1,6 +1,6 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' original/api_album.py patched/api_album.py ---- original/api_album.py 2013-08-07 21:13:32.151830000 +0100 -+++ patched/api_album.py 2013-08-07 21:13:59.879967978 +0100 +--- original/api_album.py 2013-08-12 17:24:58.207574000 +0100 ++++ patched/api_album.py 2013-08-12 17:27:10.872232623 +0100 @@ -1,6 +1,7 @@ + # pylint: disable=C0111 from .objects import Album @@ -20,8 +20,8 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' original/api_album. self._client = client diff --unified --recursive '--exclude=.pylint-ignores.patch' original/api_photo.py patched/api_photo.py ---- original/api_photo.py 2013-08-07 21:13:32.151830000 +0100 -+++ patched/api_photo.py 2013-08-07 21:13:59.879967978 +0100 +--- original/api_photo.py 2013-08-12 17:24:58.207574000 +0100 ++++ patched/api_photo.py 2013-08-12 17:27:10.872232623 +0100 @@ -1,3 +1,4 @@ + # pylint: disable=C0111 import base64 @@ -46,8 +46,8 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' original/api_photo. self._client = client diff --unified --recursive '--exclude=.pylint-ignores.patch' original/api_tag.py patched/api_tag.py ---- original/api_tag.py 2013-08-07 21:13:32.151830000 +0100 -+++ patched/api_tag.py 2013-08-07 21:13:59.879967978 +0100 +--- original/api_tag.py 2013-08-12 17:24:58.211574000 +0100 ++++ patched/api_tag.py 2013-08-12 17:27:10.872232623 +0100 @@ -1,6 +1,7 @@ + # pylint: disable=C0111 from .objects import Tag @@ -67,8 +67,8 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' original/api_tag.py self._client = client diff --unified --recursive '--exclude=.pylint-ignores.patch' original/config.py patched/config.py ---- original/config.py 2013-08-07 21:13:32.151830000 +0100 -+++ patched/config.py 2013-08-07 21:13:59.879967978 +0100 +--- original/config.py 2013-08-12 17:24:58.211574000 +0100 ++++ patched/config.py 2013-08-12 17:27:10.872232623 +0100 @@ -1,7 +1,8 @@ + # pylint: disable=C0111 from __future__ import unicode_literals @@ -100,28 +100,24 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' original/config.py parser.readfp(buf) # Python2 diff --unified --recursive '--exclude=.pylint-ignores.patch' original/errors.py patched/errors.py ---- original/errors.py 2013-08-07 21:13:32.151830000 +0100 -+++ patched/errors.py 2013-08-07 21:13:59.879967978 +0100 +--- original/errors.py 2013-08-12 17:24:58.211574000 +0100 ++++ patched/errors.py 2013-08-12 17:27:10.872232623 +0100 @@ -1,3 +1,4 @@ + # pylint: disable=C0111 class TroveboxError(Exception): """ Indicates that an Trovebox operation failed """ pass diff --unified --recursive '--exclude=.pylint-ignores.patch' original/http.py patched/http.py ---- original/http.py 2013-08-07 21:13:32.151830000 +0100 -+++ patched/http.py 2013-08-07 21:13:59.879967978 +0100 -@@ -1,21 +1,22 @@ -+ # pylint: disable=C0111 - from __future__ import unicode_literals - import sys - import requests +--- original/http.py 2013-08-12 17:24:58.211574000 +0100 ++++ patched/http.py 2013-08-12 17:27:23.828296874 +0100 +@@ -4,18 +4,18 @@ import requests_oauthlib import logging try: -- from urllib.parse import urlunparse # Python3 -+ from urllib.parse import urlunparse # Python3 # pylint: disable=F0401,E0611 +- from urllib.parse import urlparse, urlunparse # Python3 ++ from urllib.parse import urlparse, urlunparse # Python3 # pylint: disable=F0401,E0611 except ImportError: - from urlparse import urlunparse # Python2 + from urlparse import urlparse, urlunparse # Python2 from .objects import TroveboxObject -from .errors import * @@ -137,7 +133,7 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' original/http.py pa DUPLICATE_RESPONSE = {"code": 409, "message": "This photo already exists"} -@@ -32,7 +33,7 @@ +@@ -32,7 +32,7 @@ This should be used to ensure that your application will continue to work even if the Trovebox API is updated to a new revision. """ @@ -147,8 +143,8 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' original/http.py pa token='', token_secret='', api_version=None): self._api_version = api_version diff --unified --recursive '--exclude=.pylint-ignores.patch' original/__init__.py patched/__init__.py ---- original/__init__.py 2013-08-07 21:13:32.151830000 +0100 -+++ patched/__init__.py 2013-08-07 21:13:59.879967978 +0100 +--- original/__init__.py 2013-08-12 17:24:58.211574000 +0100 ++++ patched/__init__.py 2013-08-12 17:27:10.872232623 +0100 @@ -1,5 +1,6 @@ + # pylint: disable=C0111 from .http import Http @@ -167,8 +163,8 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' original/__init__.p token='', token_secret='', api_version=None): diff --unified --recursive '--exclude=.pylint-ignores.patch' original/main.py patched/main.py ---- original/main.py 2013-08-07 21:13:32.151830000 +0100 -+++ patched/main.py 2013-08-07 21:13:59.883967994 +0100 +--- original/main.py 2013-08-12 17:24:58.211574000 +0100 ++++ patched/main.py 2013-08-12 17:27:10.872232623 +0100 @@ -1,3 +1,4 @@ + # pylint: disable=C0111 #!/usr/bin/env python @@ -201,8 +197,8 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' original/main.py pa if options.verbose: diff --unified --recursive '--exclude=.pylint-ignores.patch' original/objects.py patched/objects.py ---- original/objects.py 2013-08-07 21:13:32.155830000 +0100 -+++ patched/objects.py 2013-08-07 21:13:59.883967994 +0100 +--- original/objects.py 2013-08-12 17:24:58.211574000 +0100 ++++ patched/objects.py 2013-08-12 17:27:10.872232623 +0100 @@ -1,14 +1,15 @@ + # pylint: disable=C0111 try: @@ -223,8 +219,8 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' original/objects.py self._trovebox = trovebox self._json_dict = json_dict diff --unified --recursive '--exclude=.pylint-ignores.patch' original/_version.py patched/_version.py ---- original/_version.py 2013-08-07 21:12:22.487484000 +0100 -+++ patched/_version.py 2013-08-07 21:14:05.947998060 +0100 +--- original/_version.py 2013-08-12 17:24:58.211574000 +0100 ++++ patched/_version.py 2013-08-12 17:27:10.872232623 +0100 @@ -1 +1,2 @@ + # pylint: disable=C0111 __version__ = "0.4" diff --git a/trovebox/http.py b/trovebox/http.py index 6d45d31..97b9a0b 100644 --- a/trovebox/http.py +++ b/trovebox/http.py @@ -4,9 +4,9 @@ import requests import requests_oauthlib import logging try: - from urllib.parse import urlunparse # Python3 + from urllib.parse import urlparse, urlunparse # Python3 except ImportError: - from urlparse import urlunparse # Python2 + from urlparse import urlparse, urlunparse # Python2 from .objects import TroveboxObject from .errors import * @@ -62,11 +62,7 @@ class Http(object): Returns the raw response if process_response=False """ params = self._process_params(params) - if not endpoint.startswith("/"): - endpoint = "/" + endpoint - if self._api_version is not None: - endpoint = "/v%d%s" % (self._api_version, endpoint) - url = urlunparse(('http', self.host, endpoint, '', '', '')) + url = self._construct_url(endpoint) if self.config.consumer_key: auth = requests_oauthlib.OAuth1(self.config.consumer_key, @@ -105,11 +101,7 @@ class Http(object): Returns the raw response if process_response=False """ params = self._process_params(params) - if not endpoint.startswith("/"): - endpoint = "/" + endpoint - if self._api_version is not None: - endpoint = "/v%d%s" % (self._api_version, endpoint) - url = urlunparse(('http', self.host, endpoint, '', '', '')) + url = self._construct_url(endpoint) if not self.config.consumer_key: raise TroveboxError("Cannot issue POST without OAuth tokens") @@ -146,6 +138,22 @@ class Http(object): else: return response.text + def _construct_url(self, endpoint): + """Return the full URL to the specified endpoint""" + parsed_url = urlparse(self.host) + scheme = parsed_url[0] + host = parsed_url[1] + # Handle host without a scheme specified (eg. www.example.com) + if scheme == "": + scheme = "http" + host = self.host + + if not endpoint.startswith("/"): + endpoint = "/" + endpoint + if self._api_version is not None: + endpoint = "/v%d%s" % (self._api_version, endpoint) + return urlunparse((scheme, host, endpoint, '', '', '')) + @staticmethod def _process_params(params): """ Converts Unicode/lists/booleans inside HTTP parameters """ From 32965c716ece6c48a056091d9225c9d408db29c2 Mon Sep 17 00:00:00 2001 From: Pete Date: Mon, 12 Aug 2013 18:06:22 +0100 Subject: [PATCH 11/19] Add docstrings to the top of each file, since these are not easily ignored in Pylint --- trovebox/.pylint-ignores.patch | 127 ++++++++++++++++++--------------- trovebox/__init__.py | 3 + trovebox/_version.py | 1 + trovebox/api_album.py | 3 + trovebox/api_photo.py | 3 + trovebox/api_tag.py | 3 + trovebox/config.py | 3 + trovebox/errors.py | 3 + trovebox/http.py | 3 + trovebox/main.py | 3 + trovebox/objects.py | 3 + 11 files changed, 97 insertions(+), 58 deletions(-) diff --git a/trovebox/.pylint-ignores.patch b/trovebox/.pylint-ignores.patch index 52deaf8..4b2b1c9 100644 --- a/trovebox/.pylint-ignores.patch +++ b/trovebox/.pylint-ignores.patch @@ -1,8 +1,8 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' original/api_album.py patched/api_album.py ---- original/api_album.py 2013-08-12 17:24:58.207574000 +0100 -+++ patched/api_album.py 2013-08-12 17:27:10.872232623 +0100 -@@ -1,6 +1,7 @@ -+ # pylint: disable=C0111 +--- original/api_album.py 2013-08-12 18:02:57.510877000 +0100 ++++ patched/api_album.py 2013-08-12 18:03:40.123088539 +0100 +@@ -3,7 +3,7 @@ + """ from .objects import Album -class ApiAlbums(object): @@ -10,7 +10,7 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' original/api_album. def __init__(self, client): self._client = client -@@ -9,7 +10,7 @@ +@@ -12,7 +12,7 @@ results = self._client.get("/albums/list.json", **kwds)["result"] return [Album(self._client, album) for album in results] @@ -20,14 +20,9 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' original/api_album. self._client = client diff --unified --recursive '--exclude=.pylint-ignores.patch' original/api_photo.py patched/api_photo.py ---- original/api_photo.py 2013-08-12 17:24:58.207574000 +0100 -+++ patched/api_photo.py 2013-08-12 17:27:10.872232623 +0100 -@@ -1,3 +1,4 @@ -+ # pylint: disable=C0111 - import base64 - - from .errors import TroveboxError -@@ -17,7 +18,7 @@ +--- original/api_photo.py 2013-08-12 18:02:57.510877000 +0100 ++++ patched/api_photo.py 2013-08-12 18:03:40.123088539 +0100 +@@ -20,7 +20,7 @@ ids.append(photo) return ids @@ -36,7 +31,7 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' original/api_photo. def __init__(self, client): self._client = client -@@ -51,7 +52,7 @@ +@@ -54,7 +54,7 @@ raise TroveboxError("Delete response returned False") return True @@ -46,10 +41,10 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' original/api_photo. self._client = client diff --unified --recursive '--exclude=.pylint-ignores.patch' original/api_tag.py patched/api_tag.py ---- original/api_tag.py 2013-08-12 17:24:58.211574000 +0100 -+++ patched/api_tag.py 2013-08-12 17:27:10.872232623 +0100 -@@ -1,6 +1,7 @@ -+ # pylint: disable=C0111 +--- original/api_tag.py 2013-08-12 18:02:57.510877000 +0100 ++++ patched/api_tag.py 2013-08-12 18:03:40.123088539 +0100 +@@ -3,7 +3,7 @@ + """ from .objects import Tag -class ApiTags(object): @@ -57,7 +52,7 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' original/api_tag.py def __init__(self, client): self._client = client -@@ -9,7 +10,7 @@ +@@ -12,7 +12,7 @@ results = self._client.get("/tags/list.json", **kwds)["result"] return [Tag(self._client, tag) for tag in results] @@ -67,10 +62,9 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' original/api_tag.py self._client = client diff --unified --recursive '--exclude=.pylint-ignores.patch' original/config.py patched/config.py ---- original/config.py 2013-08-12 17:24:58.211574000 +0100 -+++ patched/config.py 2013-08-12 17:27:10.872232623 +0100 -@@ -1,7 +1,8 @@ -+ # pylint: disable=C0111 +--- original/config.py 2013-08-12 18:02:57.510877000 +0100 ++++ patched/config.py 2013-08-12 18:03:40.123088539 +0100 +@@ -4,7 +4,7 @@ from __future__ import unicode_literals import os try: @@ -79,7 +73,7 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' original/config.py except ImportError: from ConfigParser import SafeConfigParser as ConfigParser # Python2 try: -@@ -9,8 +10,8 @@ +@@ -12,8 +12,8 @@ except ImportError: import StringIO as io # Python2 @@ -90,7 +84,7 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' original/config.py consumer_key, consumer_secret, token, token_secret): if host is None: -@@ -65,7 +66,7 @@ +@@ -68,7 +68,7 @@ parser = ConfigParser() parser.optionxform = str # Case-sensitive options try: @@ -99,18 +93,10 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' original/config.py except AttributeError: parser.readfp(buf) # Python2 -diff --unified --recursive '--exclude=.pylint-ignores.patch' original/errors.py patched/errors.py ---- original/errors.py 2013-08-12 17:24:58.211574000 +0100 -+++ patched/errors.py 2013-08-12 17:27:10.872232623 +0100 -@@ -1,3 +1,4 @@ -+ # pylint: disable=C0111 - class TroveboxError(Exception): - """ Indicates that an Trovebox operation failed """ - pass diff --unified --recursive '--exclude=.pylint-ignores.patch' original/http.py patched/http.py ---- original/http.py 2013-08-12 17:24:58.211574000 +0100 -+++ patched/http.py 2013-08-12 17:27:23.828296874 +0100 -@@ -4,18 +4,18 @@ +--- original/http.py 2013-08-12 18:02:57.510877000 +0100 ++++ patched/http.py 2013-08-12 18:03:40.123088539 +0100 +@@ -7,18 +7,18 @@ import requests_oauthlib import logging try: @@ -133,7 +119,7 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' original/http.py pa DUPLICATE_RESPONSE = {"code": 409, "message": "This photo already exists"} -@@ -32,7 +32,7 @@ +@@ -35,7 +35,7 @@ This should be used to ensure that your application will continue to work even if the Trovebox API is updated to a new revision. """ @@ -143,17 +129,18 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' original/http.py pa token='', token_secret='', api_version=None): self._api_version = api_version diff --unified --recursive '--exclude=.pylint-ignores.patch' original/__init__.py patched/__init__.py ---- original/__init__.py 2013-08-12 17:24:58.211574000 +0100 -+++ patched/__init__.py 2013-08-12 17:27:10.872232623 +0100 -@@ -1,5 +1,6 @@ -+ # pylint: disable=C0111 +--- original/__init__.py 2013-08-12 18:02:57.514877000 +0100 ++++ patched/__init__.py 2013-08-12 18:03:40.123088539 +0100 +@@ -2,7 +2,7 @@ + __init__.py : Trovebox package top level + """ from .http import Http -from .errors import * +from .errors import * # pylint: disable=W0401 from ._version import __version__ from . import api_photo from . import api_tag -@@ -19,7 +20,7 @@ +@@ -22,7 +22,7 @@ This should be used to ensure that your application will continue to work even if the Trovebox API is updated to a new revision. """ @@ -163,14 +150,9 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' original/__init__.p token='', token_secret='', api_version=None): diff --unified --recursive '--exclude=.pylint-ignores.patch' original/main.py patched/main.py ---- original/main.py 2013-08-12 17:24:58.211574000 +0100 -+++ patched/main.py 2013-08-12 17:27:10.872232623 +0100 -@@ -1,3 +1,4 @@ -+ # pylint: disable=C0111 - #!/usr/bin/env python - import os - import sys -@@ -23,7 +24,7 @@ +--- original/main.py 2013-08-12 18:02:57.514877000 +0100 ++++ patched/main.py 2013-08-12 18:03:40.123088539 +0100 +@@ -26,7 +26,7 @@ ################################################################# @@ -179,7 +161,7 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' original/main.py pa usage = "%prog --help" parser = OptionParser(usage, add_help_option=False) parser.add_option('-c', '--config', help="Configuration file to use", -@@ -81,13 +82,13 @@ +@@ -84,13 +84,13 @@ sys.exit(1) if options.method == "GET": @@ -197,10 +179,11 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' original/main.py pa if options.verbose: diff --unified --recursive '--exclude=.pylint-ignores.patch' original/objects.py patched/objects.py ---- original/objects.py 2013-08-12 17:24:58.211574000 +0100 -+++ patched/objects.py 2013-08-12 17:27:10.872232623 +0100 -@@ -1,14 +1,15 @@ -+ # pylint: disable=C0111 +--- original/objects.py 2013-08-12 18:03:37.079073000 +0100 ++++ patched/objects.py 2013-08-12 18:04:00.723190687 +0100 +@@ -2,16 +2,16 @@ + objects.py : Basic Trovebox API Objects + """ try: - from urllib.parse import quote # Python3 + from urllib.parse import quote # Python3 # pylint: disable=F0401,E0611 @@ -218,9 +201,37 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' original/objects.py self.name = None self._trovebox = trovebox self._json_dict = json_dict +@@ -57,7 +57,7 @@ + return self._json_dict + + +-class Photo(TroveboxObject): ++class Photo(TroveboxObject): # pylint: disable=C0111 + def delete(self, **kwds): + """ + Delete this photo. +@@ -147,7 +147,7 @@ + + self._replace_fields(new_dict) + +-class Tag(TroveboxObject): ++class Tag(TroveboxObject): # pylint: disable=C0111 + def delete(self, **kwds): + """ + Delete this tag. +@@ -168,7 +168,7 @@ + self._replace_fields(new_dict) + + +-class Album(TroveboxObject): ++class Album(TroveboxObject): # pylint: disable=C0111 + def __init__(self, trovebox, json_dict): + self.photos = None + self.cover = None diff --unified --recursive '--exclude=.pylint-ignores.patch' original/_version.py patched/_version.py ---- original/_version.py 2013-08-12 17:24:58.211574000 +0100 -+++ patched/_version.py 2013-08-12 17:27:10.872232623 +0100 -@@ -1 +1,2 @@ +--- original/_version.py 2013-08-12 18:02:57.514877000 +0100 ++++ patched/_version.py 2013-08-12 18:03:40.127088555 +0100 +@@ -1,2 +1,2 @@ +- + # pylint: disable=C0111 __version__ = "0.4" diff --git a/trovebox/__init__.py b/trovebox/__init__.py index c1118e2..f8b0a28 100644 --- a/trovebox/__init__.py +++ b/trovebox/__init__.py @@ -1,3 +1,6 @@ +""" +__init__.py : Trovebox package top level +""" from .http import Http from .errors import * from ._version import __version__ diff --git a/trovebox/_version.py b/trovebox/_version.py index 896a370..15ae4dc 100644 --- a/trovebox/_version.py +++ b/trovebox/_version.py @@ -1 +1,2 @@ + __version__ = "0.4" diff --git a/trovebox/api_album.py b/trovebox/api_album.py index 79dfe29..4b69f87 100644 --- a/trovebox/api_album.py +++ b/trovebox/api_album.py @@ -1,3 +1,6 @@ +""" +api_album.py : Trovebox Album API Classes +""" from .objects import Album class ApiAlbums(object): diff --git a/trovebox/api_photo.py b/trovebox/api_photo.py index 75783df..702a3de 100644 --- a/trovebox/api_photo.py +++ b/trovebox/api_photo.py @@ -1,3 +1,6 @@ +""" +api_photo.py : Trovebox Photo API Classes +""" import base64 from .errors import TroveboxError diff --git a/trovebox/api_tag.py b/trovebox/api_tag.py index d80a9d1..0a694a6 100644 --- a/trovebox/api_tag.py +++ b/trovebox/api_tag.py @@ -1,3 +1,6 @@ +""" +api_tag.py : Trovebox Tag API Classes +""" from .objects import Tag class ApiTags(object): diff --git a/trovebox/config.py b/trovebox/config.py index e18f30b..69a2739 100644 --- a/trovebox/config.py +++ b/trovebox/config.py @@ -1,3 +1,6 @@ +""" +config.py : OAuth Config File Parser +""" from __future__ import unicode_literals import os try: diff --git a/trovebox/errors.py b/trovebox/errors.py index c813e5a..15b13cc 100644 --- a/trovebox/errors.py +++ b/trovebox/errors.py @@ -1,3 +1,6 @@ +""" +errors.py : Trovebox Error Classes +""" class TroveboxError(Exception): """ Indicates that an Trovebox operation failed """ pass diff --git a/trovebox/http.py b/trovebox/http.py index 97b9a0b..0a3d257 100644 --- a/trovebox/http.py +++ b/trovebox/http.py @@ -1,3 +1,6 @@ +""" +http.py : Trovebox HTTP Access +""" from __future__ import unicode_literals import sys import requests diff --git a/trovebox/main.py b/trovebox/main.py index 7472bc6..b7b84e4 100644 --- a/trovebox/main.py +++ b/trovebox/main.py @@ -1,4 +1,7 @@ #!/usr/bin/env python +""" +main.py : Trovebox Console Script +""" import os import sys import json diff --git a/trovebox/objects.py b/trovebox/objects.py index 805983f..7c1335a 100644 --- a/trovebox/objects.py +++ b/trovebox/objects.py @@ -1,3 +1,6 @@ +""" +objects.py : Basic Trovebox API Objects +""" try: from urllib.parse import quote # Python3 except ImportError: From d7b74dc1da88ec9f14ebec981ff7480a14d4e243 Mon Sep 17 00:00:00 2001 From: sneakypete81 Date: Wed, 14 Aug 2013 08:24:18 +0100 Subject: [PATCH 12/19] Rename config to auth --- tests/unit/{test_config.py => test_auth.py} | 44 ++++++++++----------- tests/unit/test_http.py | 2 +- trovebox/{config.py => auth.py} | 4 +- trovebox/http.py | 34 ++++++++-------- 4 files changed, 42 insertions(+), 42 deletions(-) rename tests/unit/{test_config.py => test_auth.py} (71%) rename trovebox/{config.py => auth.py} (97%) diff --git a/tests/unit/test_config.py b/tests/unit/test_auth.py similarity index 71% rename from tests/unit/test_config.py rename to tests/unit/test_auth.py index a671bfe..bf70160 100644 --- a/tests/unit/test_config.py +++ b/tests/unit/test_auth.py @@ -10,7 +10,7 @@ from trovebox import Trovebox CONFIG_HOME_PATH = os.path.join("tests", "config") CONFIG_PATH = os.path.join(CONFIG_HOME_PATH, "trovebox") -class TestConfig(unittest.TestCase): +class TestAuth(unittest.TestCase): def setUp(self): """ Override XDG_CONFIG_HOME env var, to use test configs """ try: @@ -42,47 +42,47 @@ class TestConfig(unittest.TestCase): """ Ensure the default config is loaded """ self.create_config("default", "Test Default Host") client = Trovebox() - config = client.config + auth = client.auth self.assertEqual(client.host, "Test Default Host") - self.assertEqual(config.consumer_key, "default_consumer_key") - self.assertEqual(config.consumer_secret, "default_consumer_secret") - self.assertEqual(config.token, "default_token") - self.assertEqual(config.token_secret, "default_token_secret") + self.assertEqual(auth.consumer_key, "default_consumer_key") + self.assertEqual(auth.consumer_secret, "default_consumer_secret") + self.assertEqual(auth.token, "default_token") + self.assertEqual(auth.token_secret, "default_token_secret") def test_custom_config(self): """ Ensure a custom config can be loaded """ self.create_config("default", "Test Default Host") self.create_config("custom", "Test Custom Host") client = Trovebox(config_file="custom") - config = client.config + auth = client.auth self.assertEqual(client.host, "Test Custom Host") - self.assertEqual(config.consumer_key, "custom_consumer_key") - self.assertEqual(config.consumer_secret, "custom_consumer_secret") - self.assertEqual(config.token, "custom_token") - self.assertEqual(config.token_secret, "custom_token_secret") + self.assertEqual(auth.consumer_key, "custom_consumer_key") + self.assertEqual(auth.consumer_secret, "custom_consumer_secret") + self.assertEqual(auth.token, "custom_token") + self.assertEqual(auth.token_secret, "custom_token_secret") def test_full_config_path(self): """ Ensure a full custom config path can be loaded """ self.create_config("path", "Test Path Host") full_path = os.path.abspath(CONFIG_PATH) client = Trovebox(config_file=os.path.join(full_path, "path")) - config = client.config + auth = client.auth self.assertEqual(client.host, "Test Path Host") - self.assertEqual(config.consumer_key, "path_consumer_key") - self.assertEqual(config.consumer_secret, "path_consumer_secret") - self.assertEqual(config.token, "path_token") - self.assertEqual(config.token_secret, "path_token_secret") + self.assertEqual(auth.consumer_key, "path_consumer_key") + self.assertEqual(auth.consumer_secret, "path_consumer_secret") + self.assertEqual(auth.token, "path_token") + self.assertEqual(auth.token_secret, "path_token_secret") def test_host_override(self): """ Ensure that specifying a host overrides the default config """ self.create_config("default", "Test Default Host") client = Trovebox(host="host_override") - config = client.config - self.assertEqual(config.host, "host_override") - self.assertEqual(config.consumer_key, "") - self.assertEqual(config.consumer_secret, "") - self.assertEqual(config.token, "") - self.assertEqual(config.token_secret, "") + auth = client.auth + self.assertEqual(auth.host, "host_override") + self.assertEqual(auth.consumer_key, "") + self.assertEqual(auth.consumer_secret, "") + self.assertEqual(auth.token, "") + self.assertEqual(auth.token_secret, "") def test_missing_config_files(self): """ Ensure that missing config files raise exceptions """ diff --git a/tests/unit/test_http.py b/tests/unit/test_http.py index 9235453..2e82dae 100644 --- a/tests/unit/test_http.py +++ b/tests/unit/test_http.py @@ -44,7 +44,7 @@ class TestHttp(unittest.TestCase): def test_attributes(self): """Check that the host attribute has been set correctly""" self.assertEqual(self.client.host, self.test_host) - self.assertEqual(self.client.config.host, self.test_host) + self.assertEqual(self.client.auth.host, self.test_host) @httpretty.activate def test_get_with_http_scheme(self): diff --git a/trovebox/config.py b/trovebox/auth.py similarity index 97% rename from trovebox/config.py rename to trovebox/auth.py index 69a2739..427defc 100644 --- a/trovebox/config.py +++ b/trovebox/auth.py @@ -1,5 +1,5 @@ """ -config.py : OAuth Config File Parser +auth.py : OAuth Config File Parser """ from __future__ import unicode_literals import os @@ -12,7 +12,7 @@ try: except ImportError: import StringIO as io # Python2 -class Config(object): +class Auth(object): def __init__(self, config_file, host, consumer_key, consumer_secret, token, token_secret): diff --git a/trovebox/http.py b/trovebox/http.py index 0a3d257..bd99ddb 100644 --- a/trovebox/http.py +++ b/trovebox/http.py @@ -13,7 +13,7 @@ except ImportError: from .objects import TroveboxObject from .errors import * -from .config import Config +from .auth import Auth if sys.version < '3': TEXT_TYPE = unicode @@ -26,8 +26,8 @@ DUPLICATE_RESPONSE = {"code": 409, class Http(object): """ Base class to handle HTTP requests to an Trovebox server. - If no parameters are specified, config is loaded from the default - location (~/.config/trovebox/default). + If no parameters are specified, auth config is loaded from the + default location (~/.config/trovebox/default). The config_file parameter is used to specify an alternate config file. If the host parameter is specified, no config file is loaded and OAuth tokens (consumer*, token*) can optionally be specified. @@ -42,11 +42,11 @@ class Http(object): self._logger = logging.getLogger("trovebox") - self.config = Config(config_file, host, - consumer_key, consumer_secret, - token, token_secret) + self.auth = Auth(config_file, host, + consumer_key, consumer_secret, + token, token_secret) - self.host = self.config.host + self.host = self.auth.host # Remember the most recent HTTP request and response self.last_url = None @@ -67,11 +67,11 @@ class Http(object): params = self._process_params(params) url = self._construct_url(endpoint) - if self.config.consumer_key: - auth = requests_oauthlib.OAuth1(self.config.consumer_key, - self.config.consumer_secret, - self.config.token, - self.config.token_secret) + if self.auth.consumer_key: + auth = requests_oauthlib.OAuth1(self.auth.consumer_key, + self.auth.consumer_secret, + self.auth.token, + self.auth.token_secret) else: auth = None @@ -106,13 +106,13 @@ class Http(object): params = self._process_params(params) url = self._construct_url(endpoint) - if not self.config.consumer_key: + if not self.auth.consumer_key: raise TroveboxError("Cannot issue POST without OAuth tokens") - auth = requests_oauthlib.OAuth1(self.config.consumer_key, - self.config.consumer_secret, - self.config.token, - self.config.token_secret) + auth = requests_oauthlib.OAuth1(self.auth.consumer_key, + self.auth.consumer_secret, + self.auth.token, + self.auth.token_secret) with requests.Session() as session: if files: # Need to pass parameters as URL query, so they get OAuth signed From 5ad540e177ae40fa3a87c0807811ab3dcdb54707 Mon Sep 17 00:00:00 2001 From: sneakypete81 Date: Fri, 16 Aug 2013 08:10:33 +0100 Subject: [PATCH 13/19] Added configure method Added support for disabling HTTPS SSL verification --- README.rst | 11 ++++++++--- tests/unit/test_http.py | 34 +++++++++++++++++++++++++++++++--- trovebox/http.py | 36 ++++++++++++++++++++++++++++++------ 3 files changed, 69 insertions(+), 12 deletions(-) diff --git a/README.rst b/README.rst index 9c5125a..23f9a57 100644 --- a/README.rst +++ b/README.rst @@ -77,11 +77,16 @@ API Versioning ============== It may be useful to lock your application to a particular version of the Trovebox API. This ensures that future API updates won't cause unexpected breakages. +To do this, configure your Trovebox client as follows: -To do this, add the optional ``api_version`` parameter when creating the client object:: + client.configure(api_version=2) - from trovebox import Trovebox - client = Trovebox(api_version=2) +SSL Verification +================ +If you connect to your Trovebox server over HTTPS, its SSL certificate is automatically verified. +You can configure your Trovebox client to bypass this verification step: + + client.configure(ssl_verify=False) Commandline Tool ================ diff --git a/tests/unit/test_http.py b/tests/unit/test_http.py index 2e82dae..82df5ed 100644 --- a/tests/unit/test_http.py +++ b/tests/unit/test_http.py @@ -1,6 +1,7 @@ from __future__ import unicode_literals import os import json +import mock import httpretty try: import unittest2 as unittest # Python2.6 @@ -219,7 +220,8 @@ class TestHttp(unittest.TestCase): @httpretty.activate def test_get_with_api_version(self): """Check that an API version can be specified for the get method""" - self.client = trovebox.Trovebox(host=self.test_host, api_version=1) + self.client = trovebox.Trovebox(host=self.test_host) + self.client.configure(api_version=1) self._register_uri(httpretty.GET, uri="http://%s/v1/%s" % (self.test_host, self.test_endpoint)) @@ -228,13 +230,39 @@ class TestHttp(unittest.TestCase): @httpretty.activate def test_post_with_api_version(self): """Check that an API version can be specified for the post method""" - self.client = trovebox.Trovebox(host=self.test_host, api_version=1, - **self.test_oauth) + self.client = trovebox.Trovebox(host=self.test_host, **self.test_oauth) + self.client.configure(api_version=1) self._register_uri(httpretty.POST, uri="http://%s/v1/%s" % (self.test_host, self.test_endpoint)) self.client.post(self.test_endpoint) + @mock.patch.object(trovebox.http.requests, 'Session') + def test_get_with_ssl_verify_disabled(self, mock_session): + """Check that SSL verification can be disabled for the get method""" + session = mock_session.return_value.__enter__.return_value + session.get.return_value.text = "response text" + session.get.return_value.status_code = 200 + session.get.return_value.json.return_value = self.test_data + + self.client = trovebox.Trovebox(host=self.test_host, **self.test_oauth) + self.client.configure(ssl_verify=False) + self.client.get(self.test_endpoint) + self.assertEqual(session.verify, False) + + @mock.patch.object(trovebox.http.requests, 'Session') + def test_post_with_ssl_verify_disabled(self, mock_session): + """Check that SSL verification can be disabled for the post method""" + session = mock_session.return_value.__enter__.return_value + session.post.return_value.text = "response text" + session.post.return_value.status_code = 200 + session.post.return_value.json.return_value = self.test_data + + self.client = trovebox.Trovebox(host=self.test_host, **self.test_oauth) + self.client.configure(ssl_verify=False) + self.client.post(self.test_endpoint) + self.assertEqual(session.verify, False) + @httpretty.activate def test_post_file(self): """Check that a file can be posted""" diff --git a/trovebox/http.py b/trovebox/http.py index bd99ddb..4cc0faf 100644 --- a/trovebox/http.py +++ b/trovebox/http.py @@ -31,14 +31,22 @@ class Http(object): The config_file parameter is used to specify an alternate config file. If the host parameter is specified, no config file is loaded and OAuth tokens (consumer*, token*) can optionally be specified. - All requests will include the api_version path, if specified. - This should be used to ensure that your application will continue to work - even if the Trovebox API is updated to a new revision. """ + + _CONFIG_DEFAULTS = {"api_version" : None, + "ssl_verify" : True, + } + def __init__(self, config_file=None, host=None, consumer_key='', consumer_secret='', token='', token_secret='', api_version=None): - self._api_version = api_version + + self.config = dict(self._CONFIG_DEFAULTS) + + if api_version is not None: + print("Deprecation Warning: api_version should be set by " + "calling the configure function") + self.config["api_version"] = api_version self._logger = logging.getLogger("trovebox") @@ -53,6 +61,20 @@ class Http(object): self.last_params = None self.last_response = None + def configure(self, **kwds): + """ + Update Trovebox HTTP client configuration. + + :param api_version: Include a Trovebox API version in all requests. + This can be used to ensure that your application will continue + to work even if the Trovebox API is updated to a new revision. + [default: None] + :param ssl_verify: If true, HTTPS SSL certificates will always be + verified [default: True] + """ + for item in kwds: + self.config[item] = kwds[item] + def get(self, endpoint, process_response=True, **params): """ Performs an HTTP GET from the specified endpoint (API path), @@ -76,6 +98,7 @@ class Http(object): auth = None with requests.Session() as session: + session.verify = self.config["ssl_verify"] response = session.get(url, params=params, auth=auth) self._logger.info("============================") @@ -114,6 +137,7 @@ class Http(object): self.auth.token, self.auth.token_secret) with requests.Session() as session: + session.verify = self.config["ssl_verify"] if files: # Need to pass parameters as URL query, so they get OAuth signed response = session.post(url, params=params, @@ -153,8 +177,8 @@ class Http(object): if not endpoint.startswith("/"): endpoint = "/" + endpoint - if self._api_version is not None: - endpoint = "/v%d%s" % (self._api_version, endpoint) + if self.config["api_version"] is not None: + endpoint = "/v%d%s" % (self.config["api_version"], endpoint) return urlunparse((scheme, host, endpoint, '', '', '')) @staticmethod From ec163eb4d4d45a0ee1412634968570aa7ccec436 Mon Sep 17 00:00:00 2001 From: sneakypete81 Date: Fri, 16 Aug 2013 17:46:30 +0100 Subject: [PATCH 14/19] Add DDT support to test_http, to reduce duplication --- tests/README.markdown | 3 +- tests/unit/test_http.py | 145 +++++++++++++--------------------------- tox.ini | 2 + 3 files changed, 52 insertions(+), 98 deletions(-) diff --git a/tests/README.markdown b/tests/README.markdown index 3aa3d35..4aef0d6 100644 --- a/tests/README.markdown +++ b/tests/README.markdown @@ -12,6 +12,7 @@ They run very quickly and don't require any external test hosts. #### Requirements * mock >= 1.0.0 * httpretty >= 0.6.1 + * ddt >= 0.3.0 * tox (optional) #### Running the Unit Tests @@ -19,7 +20,7 @@ They run very quickly and don't require any external test hosts. python -m unittest discover tests/unit To run the unit tests against all supported Python versions, use ```tox```: - + tox ---------------------------------------- diff --git a/tests/unit/test_http.py b/tests/unit/test_http.py index 82df5ed..98883f1 100644 --- a/tests/unit/test_http.py +++ b/tests/unit/test_http.py @@ -3,6 +3,8 @@ import os import json import mock import httpretty +from httpretty import GET, POST +from ddt import ddt, data try: import unittest2 as unittest # Python2.6 except ImportError: @@ -10,6 +12,21 @@ except ImportError: import trovebox +class GetOrPost(object): + """Helper class to call the correct (GET/POST) method""" + def __init__(self, client, method): + self.client = client + self.method = method + + def call(self, *args, **kwds): + if self.method == GET: + return self.client.get(*args, **kwds) + elif self.method == POST: + return self.client.post(*args, **kwds) + else: + raise ValueError("unknown method: %s" % self.method) + +@ddt class TestHttp(unittest.TestCase): test_host = "test.example.com" test_endpoint = "test.json" @@ -48,14 +65,15 @@ class TestHttp(unittest.TestCase): self.assertEqual(self.client.auth.host, self.test_host) @httpretty.activate - def test_get_with_http_scheme(self): - """Check that the get method works with a host starting with 'http://'""" - self._register_uri(httpretty.GET, + @data(GET, POST) + def test_http_scheme(self, method): + """Check that we can access hosts starting with 'http://'""" + self._register_uri(method, uri="http://test.example.com/%s" % self.test_endpoint) self.client = trovebox.Trovebox(host="http://test.example.com", **self.test_oauth) - response = self.client.get(self.test_endpoint) + response = GetOrPost(self.client, method).call(self.test_endpoint) self.assertIn("OAuth", self._last_request().headers["authorization"]) self.assertEqual(response, self.test_data) self.assertEqual(self.client.last_url, @@ -63,14 +81,15 @@ class TestHttp(unittest.TestCase): self.assertEqual(self.client.last_response.json(), self.test_data) @httpretty.activate - def test_get_with_no_scheme(self): - """Check that the get method works with a host without a 'http://' prefix""" - self._register_uri(httpretty.GET, + @data(GET, POST) + def test_no_scheme(self, method): + """Check that we can access hosts without a 'http://' prefix""" + self._register_uri(method, uri="http://test.example.com/%s" % self.test_endpoint) self.client = trovebox.Trovebox(host="test.example.com", **self.test_oauth) - response = self.client.get(self.test_endpoint) + response = GetOrPost(self.client, method).call(self.test_endpoint) self.assertIn("OAuth", self._last_request().headers["authorization"]) self.assertEqual(response, self.test_data) self.assertEqual(self.client.last_url, @@ -78,59 +97,15 @@ class TestHttp(unittest.TestCase): self.assertEqual(self.client.last_response.json(), self.test_data) @httpretty.activate - def test_get_with_https_scheme(self): - """Check that the get method works with a host starting with 'https://'""" - self._register_uri(httpretty.GET, + @data(GET, POST) + def test_https_scheme(self, method): + """Check that we can access hosts starting with 'https://'""" + self._register_uri(method, uri="https://test.example.com/%s" % self.test_endpoint) self.client = trovebox.Trovebox(host="https://test.example.com", **self.test_oauth) - response = self.client.get(self.test_endpoint) - self.assertIn("OAuth", self._last_request().headers["authorization"]) - self.assertEqual(response, self.test_data) - self.assertEqual(self.client.last_url, - "https://test.example.com/%s" % self.test_endpoint) - self.assertEqual(self.client.last_response.json(), self.test_data) - - @httpretty.activate - def test_post_with_http_scheme(self): - """Check that the post method works with a host starting with 'http://'""" - self._register_uri(httpretty.POST, - uri="http://test.example.com/%s" % self.test_endpoint) - - self.client = trovebox.Trovebox(host="http://test.example.com", - **self.test_oauth) - response = self.client.post(self.test_endpoint) - self.assertIn("OAuth", self._last_request().headers["authorization"]) - self.assertEqual(response, self.test_data) - self.assertEqual(self.client.last_url, - "http://test.example.com/%s" % self.test_endpoint) - self.assertEqual(self.client.last_response.json(), self.test_data) - - @httpretty.activate - def test_post_with_no_scheme(self): - """Check that the post method works with a host without a 'http://' prefix""" - self._register_uri(httpretty.POST, - uri="http://test.example.com/%s" % self.test_endpoint) - - self.client = trovebox.Trovebox(host="test.example.com", - **self.test_oauth) - response = self.client.post(self.test_endpoint) - self.assertIn("OAuth", self._last_request().headers["authorization"]) - self.assertEqual(response, self.test_data) - self.assertEqual(self.client.last_url, - "http://test.example.com/%s" % self.test_endpoint) - self.assertEqual(self.client.last_response.json(), self.test_data) - - @httpretty.activate - def test_post_with_https_scheme(self): - """Check that the post method works with a host starting with 'https://'""" - self._register_uri(httpretty.POST, - uri="https://test.example.com/%s" % self.test_endpoint) - - self.client = trovebox.Trovebox(host="https://test.example.com", - **self.test_oauth) - response = self.client.post(self.test_endpoint) + response = GetOrPost(self.client, method).call(self.test_endpoint) self.assertIn("OAuth", self._last_request().headers["authorization"]) self.assertEqual(response, self.test_data) self.assertEqual(self.client.last_url, @@ -184,17 +159,12 @@ class TestHttp(unittest.TestCase): self.client.post(self.test_endpoint) @httpretty.activate - def test_get_without_response_processing(self): - """Check that the get method works with response processing disabled""" - self._register_uri(httpretty.GET) - response = self.client.get(self.test_endpoint, process_response=False) - self.assertEqual(response, json.dumps(self.test_data)) - - @httpretty.activate - def test_post_without_response_processing(self): - """Check that the post method works with response processing disabled""" - self._register_uri(httpretty.POST) - response = self.client.post(self.test_endpoint, process_response=False) + @data(GET, POST) + def test_no_response_processing(self, method): + """Check that get/post methods work with response processing disabled""" + self._register_uri(method) + response = GetOrPost(self.client, method).call(self.test_endpoint, + process_response=False) self.assertEqual(response, json.dumps(self.test_data)) @httpretty.activate @@ -218,49 +188,30 @@ class TestHttp(unittest.TestCase): self.assertIn(params["unicode_"], [["\xc3\xbcmlaut"], ["\xfcmlaut"]]) @httpretty.activate - def test_get_with_api_version(self): - """Check that an API version can be specified for the get method""" - self.client = trovebox.Trovebox(host=self.test_host) - self.client.configure(api_version=1) - self._register_uri(httpretty.GET, - uri="http://%s/v1/%s" % (self.test_host, - self.test_endpoint)) - self.client.get(self.test_endpoint) - - @httpretty.activate - def test_post_with_api_version(self): - """Check that an API version can be specified for the post method""" + @data(GET, POST) + def test_api_version(self, method): + """Check that an API version can be specified""" self.client = trovebox.Trovebox(host=self.test_host, **self.test_oauth) self.client.configure(api_version=1) - self._register_uri(httpretty.POST, + self._register_uri(method, uri="http://%s/v1/%s" % (self.test_host, self.test_endpoint)) - self.client.post(self.test_endpoint) + GetOrPost(self.client, method).call(self.test_endpoint) @mock.patch.object(trovebox.http.requests, 'Session') - def test_get_with_ssl_verify_disabled(self, mock_session): + @data(GET, POST) + def test_ssl_verify_disabled(self, method, mock_session): """Check that SSL verification can be disabled for the get method""" session = mock_session.return_value.__enter__.return_value session.get.return_value.text = "response text" session.get.return_value.status_code = 200 session.get.return_value.json.return_value = self.test_data + # Handle either post or get + session.post = session.get self.client = trovebox.Trovebox(host=self.test_host, **self.test_oauth) self.client.configure(ssl_verify=False) - self.client.get(self.test_endpoint) - self.assertEqual(session.verify, False) - - @mock.patch.object(trovebox.http.requests, 'Session') - def test_post_with_ssl_verify_disabled(self, mock_session): - """Check that SSL verification can be disabled for the post method""" - session = mock_session.return_value.__enter__.return_value - session.post.return_value.text = "response text" - session.post.return_value.status_code = 200 - session.post.return_value.json.return_value = self.test_data - - self.client = trovebox.Trovebox(host=self.test_host, **self.test_oauth) - self.client.configure(ssl_verify=False) - self.client.post(self.test_endpoint) + GetOrPost(self.client, method).call(self.test_endpoint) self.assertEqual(session.verify, False) @httpretty.activate diff --git a/tox.ini b/tox.ini index 2657d68..5e0c3da 100644 --- a/tox.ini +++ b/tox.ini @@ -6,11 +6,13 @@ commands = python -m unittest discover --catch tests/unit deps = mock >= 1.0.0 httpretty >= 0.6.1 + ddt >= 0.3.0 [testenv:py26] commands = unit2 discover --catch tests/unit deps = mock >= 1.0.0 httpretty >= 0.6.1 + ddt >= 0.3.0 unittest2 discover From 82eda4c62371ffe10b414bcca3e986ae07fcb68b Mon Sep 17 00:00:00 2001 From: sneakypete81 Date: Fri, 16 Aug 2013 17:58:18 +0100 Subject: [PATCH 15/19] Add MANIFEST.in, to be totally sure that README.rst gets packaged --- MANIFEST.in | 1 + 1 file changed, 1 insertion(+) create mode 100644 MANIFEST.in diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..9561fb1 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1 @@ +include README.rst From b0bc43b6d4b5f1fb53eafa1ad8361a50bd6fe577 Mon Sep 17 00:00:00 2001 From: sneakypete81 Date: Fri, 16 Aug 2013 18:14:40 +0100 Subject: [PATCH 16/19] Pylint fixes --- trovebox/.pylint-ignores.patch | 59 +++++++++++++++++----------------- trovebox/auth.py | 1 + 2 files changed, 31 insertions(+), 29 deletions(-) diff --git a/trovebox/.pylint-ignores.patch b/trovebox/.pylint-ignores.patch index 4b2b1c9..41fca5e 100644 --- a/trovebox/.pylint-ignores.patch +++ b/trovebox/.pylint-ignores.patch @@ -1,6 +1,6 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' original/api_album.py patched/api_album.py ---- original/api_album.py 2013-08-12 18:02:57.510877000 +0100 -+++ patched/api_album.py 2013-08-12 18:03:40.123088539 +0100 +--- original/api_album.py 2013-08-16 18:12:30.434212000 +0100 ++++ patched/api_album.py 2013-08-16 18:13:29.678506001 +0100 @@ -3,7 +3,7 @@ """ from .objects import Album @@ -20,8 +20,8 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' original/api_album. self._client = client diff --unified --recursive '--exclude=.pylint-ignores.patch' original/api_photo.py patched/api_photo.py ---- original/api_photo.py 2013-08-12 18:02:57.510877000 +0100 -+++ patched/api_photo.py 2013-08-12 18:03:40.123088539 +0100 +--- original/api_photo.py 2013-08-16 18:12:30.434212000 +0100 ++++ patched/api_photo.py 2013-08-16 18:13:29.678506001 +0100 @@ -20,7 +20,7 @@ ids.append(photo) return ids @@ -41,8 +41,8 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' original/api_photo. self._client = client diff --unified --recursive '--exclude=.pylint-ignores.patch' original/api_tag.py patched/api_tag.py ---- original/api_tag.py 2013-08-12 18:02:57.510877000 +0100 -+++ patched/api_tag.py 2013-08-12 18:03:40.123088539 +0100 +--- original/api_tag.py 2013-08-16 18:12:30.434212000 +0100 ++++ patched/api_tag.py 2013-08-16 18:13:29.678506001 +0100 @@ -3,7 +3,7 @@ """ from .objects import Tag @@ -61,9 +61,9 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' original/api_tag.py def __init__(self, client): self._client = client -diff --unified --recursive '--exclude=.pylint-ignores.patch' original/config.py patched/config.py ---- original/config.py 2013-08-12 18:02:57.510877000 +0100 -+++ patched/config.py 2013-08-12 18:03:40.123088539 +0100 +diff --unified --recursive '--exclude=.pylint-ignores.patch' original/auth.py patched/auth.py +--- original/auth.py 2013-08-16 18:13:24.966482000 +0100 ++++ patched/auth.py 2013-08-16 18:13:51.766615537 +0100 @@ -4,7 +4,7 @@ from __future__ import unicode_literals import os @@ -73,18 +73,19 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' original/config.py except ImportError: from ConfigParser import SafeConfigParser as ConfigParser # Python2 try: -@@ -12,8 +12,8 @@ +@@ -12,9 +12,9 @@ except ImportError: import StringIO as io # Python2 --class Config(object): +-class Auth(object): ++class Auth(object): # pylint: disable=R0903 + """OAuth secrets""" - def __init__(self, config_file, host, -+class Config(object): # pylint: disable=R0903,C0111 + def __init__(self, config_file, host, # pylint: disable=R0913 consumer_key, consumer_secret, token, token_secret): if host is None: -@@ -68,7 +68,7 @@ +@@ -69,7 +69,7 @@ parser = ConfigParser() parser.optionxform = str # Case-sensitive options try: @@ -94,8 +95,8 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' original/config.py parser.readfp(buf) # Python2 diff --unified --recursive '--exclude=.pylint-ignores.patch' original/http.py patched/http.py ---- original/http.py 2013-08-12 18:02:57.510877000 +0100 -+++ patched/http.py 2013-08-12 18:03:40.123088539 +0100 +--- original/http.py 2013-08-16 17:54:30.688858000 +0100 ++++ patched/http.py 2013-08-16 18:14:14.106726301 +0100 @@ -7,18 +7,18 @@ import requests_oauthlib import logging @@ -108,7 +109,7 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' original/http.py pa from .objects import TroveboxObject -from .errors import * +from .errors import * # pylint: disable=W0401 - from .config import Config + from .auth import Auth if sys.version < '3': - TEXT_TYPE = unicode @@ -119,18 +120,18 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' original/http.py pa DUPLICATE_RESPONSE = {"code": 409, "message": "This photo already exists"} -@@ -35,7 +35,7 @@ - This should be used to ensure that your application will continue to work - even if the Trovebox API is updated to a new revision. - """ +@@ -37,7 +37,7 @@ + "ssl_verify" : True, + } + - def __init__(self, config_file=None, host=None, + def __init__(self, config_file=None, host=None, # pylint: disable=R0913 consumer_key='', consumer_secret='', token='', token_secret='', api_version=None): - self._api_version = api_version + diff --unified --recursive '--exclude=.pylint-ignores.patch' original/__init__.py patched/__init__.py ---- original/__init__.py 2013-08-12 18:02:57.514877000 +0100 -+++ patched/__init__.py 2013-08-12 18:03:40.123088539 +0100 +--- original/__init__.py 2013-08-16 18:12:30.438212000 +0100 ++++ patched/__init__.py 2013-08-16 18:13:29.678506001 +0100 @@ -2,7 +2,7 @@ __init__.py : Trovebox package top level """ @@ -150,8 +151,8 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' original/__init__.p token='', token_secret='', api_version=None): diff --unified --recursive '--exclude=.pylint-ignores.patch' original/main.py patched/main.py ---- original/main.py 2013-08-12 18:02:57.514877000 +0100 -+++ patched/main.py 2013-08-12 18:03:40.123088539 +0100 +--- original/main.py 2013-08-16 18:12:30.438212000 +0100 ++++ patched/main.py 2013-08-16 18:13:29.678506001 +0100 @@ -26,7 +26,7 @@ ################################################################# @@ -179,8 +180,8 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' original/main.py pa if options.verbose: diff --unified --recursive '--exclude=.pylint-ignores.patch' original/objects.py patched/objects.py ---- original/objects.py 2013-08-12 18:03:37.079073000 +0100 -+++ patched/objects.py 2013-08-12 18:04:00.723190687 +0100 +--- original/objects.py 2013-08-16 18:12:30.438212000 +0100 ++++ patched/objects.py 2013-08-16 18:13:29.682506021 +0100 @@ -2,16 +2,16 @@ objects.py : Basic Trovebox API Objects """ @@ -229,8 +230,8 @@ diff --unified --recursive '--exclude=.pylint-ignores.patch' original/objects.py self.photos = None self.cover = None diff --unified --recursive '--exclude=.pylint-ignores.patch' original/_version.py patched/_version.py ---- original/_version.py 2013-08-12 18:02:57.514877000 +0100 -+++ patched/_version.py 2013-08-12 18:03:40.127088555 +0100 +--- original/_version.py 2013-08-16 18:12:30.438212000 +0100 ++++ patched/_version.py 2013-08-16 18:13:29.682506021 +0100 @@ -1,2 +1,2 @@ - + # pylint: disable=C0111 diff --git a/trovebox/auth.py b/trovebox/auth.py index 427defc..378ee65 100644 --- a/trovebox/auth.py +++ b/trovebox/auth.py @@ -13,6 +13,7 @@ except ImportError: import StringIO as io # Python2 class Auth(object): + """OAuth secrets""" def __init__(self, config_file, host, consumer_key, consumer_secret, token, token_secret): From da2282c43c74c5e486e58981ecea6e6fbf3813fe Mon Sep 17 00:00:00 2001 From: sneakypete81 Date: Fri, 16 Aug 2013 18:28:23 +0100 Subject: [PATCH 17/19] Fix README syntax --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 23f9a57..c656a89 100644 --- a/README.rst +++ b/README.rst @@ -77,14 +77,14 @@ API Versioning ============== It may be useful to lock your application to a particular version of the Trovebox API. This ensures that future API updates won't cause unexpected breakages. -To do this, configure your Trovebox client as follows: +To do this, configure your Trovebox client as follows:: client.configure(api_version=2) SSL Verification ================ If you connect to your Trovebox server over HTTPS, its SSL certificate is automatically verified. -You can configure your Trovebox client to bypass this verification step: +You can configure your Trovebox client to bypass this verification step:: client.configure(ssl_verify=False) From 1167f270a0b4fb15b04d0c336a5cb4fe4c2e7598 Mon Sep 17 00:00:00 2001 From: sneakypete81 Date: Fri, 16 Aug 2013 18:28:34 +0100 Subject: [PATCH 18/19] Version bump to 0.5 --- trovebox/_version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trovebox/_version.py b/trovebox/_version.py index 15ae4dc..ad57014 100644 --- a/trovebox/_version.py +++ b/trovebox/_version.py @@ -1,2 +1,2 @@ -__version__ = "0.4" +__version__ = "0.5" From 56d6432ff0d6bd660c06d95e853b1269d55672b9 Mon Sep 17 00:00:00 2001 From: sneakypete81 Date: Fri, 16 Aug 2013 18:40:42 +0100 Subject: [PATCH 19/19] Add Changelog --- CHANGELOG | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 CHANGELOG diff --git a/CHANGELOG b/CHANGELOG new file mode 100644 index 0000000..9466262 --- /dev/null +++ b/CHANGELOG @@ -0,0 +1,25 @@ +================================= +Trovebox Python Library Changelog +================================= + +v0.5 +==== + * Pylint improvements - using .pylint-ignores to waive warnings (#49) + * Add support for https URLs (#51) + * Configuration improvements (#53) + * Allow https SSL verification bypass (#50) + * Test improvements (#54) + +v0.4 +==== + +First release + + * Added more unit tests (#44, #45) + * Fixed consistency problems found with unit tests (#46) + * Renamed to Trovebox (#48) + * Packaged for PyPI: + - Updated metadata + - Store the version number inside the package, and add --version CLI option + - Update README and convert to ReStructuredText, as required by PyPI +