diff --git a/openphoto/__init__.py b/openphoto/__init__.py index 67eb995..b2523cf 100644 --- a/openphoto/__init__.py +++ b/openphoto/__init__.py @@ -1,8 +1,8 @@ -from .openphoto_http import OpenPhotoHttp -from .errors import * -from . import api_photo -from . import api_tag -from . import api_album +from openphoto.openphoto_http import OpenPhotoHttp +from openphoto.errors import * +import openphoto.api_photo +import openphoto.api_tag +import openphoto.api_album LATEST_API_VERSION = 2 @@ -26,9 +26,9 @@ class OpenPhoto(OpenPhotoHttp): consumer_key, consumer_secret, token, token_secret, api_version) - self.photos = api_photo.ApiPhotos(self) - self.photo = api_photo.ApiPhoto(self) - self.tags = api_tag.ApiTags(self) - self.tag = api_tag.ApiTag(self) - self.albums = api_album.ApiAlbums(self) - self.album = api_album.ApiAlbum(self) + self.photos = openphoto.api_photo.ApiPhotos(self) + self.photo = openphoto.api_photo.ApiPhoto(self) + self.tags = openphoto.api_tag.ApiTags(self) + self.tag = openphoto.api_tag.ApiTag(self) + self.albums = openphoto.api_album.ApiAlbums(self) + self.album = openphoto.api_album.ApiAlbum(self) diff --git a/openphoto/api_album.py b/openphoto/api_album.py index 96a31b3..819a947 100644 --- a/openphoto/api_album.py +++ b/openphoto/api_album.py @@ -1,5 +1,5 @@ -from .errors import * -from .objects import Album +from openphoto.errors import * +from openphoto.objects import Album class ApiAlbums: def __init__(self, client): diff --git a/openphoto/api_photo.py b/openphoto/api_photo.py index 033febc..e5c366b 100644 --- a/openphoto/api_photo.py +++ b/openphoto/api_photo.py @@ -1,7 +1,7 @@ import base64 -from .errors import * -from .objects import Photo +from openphoto.errors import * +from openphoto.objects import Photo class ApiPhotos: def __init__(self, client): diff --git a/openphoto/api_tag.py b/openphoto/api_tag.py index be393c0..c23d803 100644 --- a/openphoto/api_tag.py +++ b/openphoto/api_tag.py @@ -1,5 +1,5 @@ -from .errors import * -from .objects import Tag +from openphoto.errors import * +from openphoto.objects import Tag class ApiTags: def __init__(self, client): diff --git a/openphoto/config_files.py b/openphoto/config_files.py new file mode 100644 index 0000000..772f7b7 --- /dev/null +++ b/openphoto/config_files.py @@ -0,0 +1,55 @@ +from __future__ import unicode_literals +import os +try: + from configparser import ConfigParser # Python3 +except ImportError: + from ConfigParser import SafeConfigParser as ConfigParser # Python2 +try: + import io # Python3 +except ImportError: + import StringIO as io # Python2 + +def get_config_path(config_file): + config_path = os.getenv('XDG_CONFIG_HOME') + if not config_path: + config_path = os.path.join(os.getenv('HOME'), ".config") + if not config_file: + config_file = "default" + return os.path.join(config_path, "openphoto", 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. + """ + section = "DUMMY" + defaults = {'host': 'localhost', + 'consumerKey': '', 'consumerSecret': '', + 'token': '', 'tokenSecret':'', + } + # Insert an section header at the start of the config file, so ConfigParser can understand it + buf = io.StringIO() + buf.write('[%s]\n' % section) + with io.open(config_path, "r") as f: + buf.write(f.read()) + + buf.seek(0, os.SEEK_SET) + parser = ConfigParser() + parser.optionxform = str # Case-sensitive options + try: + parser.read_file(buf) # Python3 + except AttributeError: + parser.readfp(buf) # Python2 + + # Trim quotes + config = parser.items(section) + config = [(item[0].replace('"', ''), item[1].replace('"', '')) for item in config] + config = [(item[0].replace("'", ""), item[1].replace("'", "")) for item in config] + config = dict(config) + + # Apply defaults + for key in defaults: + if key not in config: + config[key] = defaults[key] + + return config diff --git a/openphoto/main.py b/openphoto/main.py index a2f944b..0bc8c59 100644 --- a/openphoto/main.py +++ b/openphoto/main.py @@ -2,13 +2,9 @@ import os import sys import string +import json from optparse import OptionParser -try: - import json -except ImportError: - import simplejson as json - from openphoto import OpenPhoto ################################################################# diff --git a/openphoto/objects.py b/openphoto/objects.py index f333847..235c96f 100644 --- a/openphoto/objects.py +++ b/openphoto/objects.py @@ -1,7 +1,7 @@ try: - from urllib.parse import quote # Python3 + from urllib.parse import quote # Python3 except ImportError: - from urllib import quote # Python2 + from urllib import quote # Python2 from .errors import * class OpenPhotoObject: diff --git a/openphoto/openphoto_http.py b/openphoto/openphoto_http.py index 7824bad..b7857e6 100644 --- a/openphoto/openphoto_http.py +++ b/openphoto/openphoto_http.py @@ -1,36 +1,26 @@ from __future__ import unicode_literals import sys import os -try: - from urllib.parse import urlunparse # Python3 -except ImportError: - from urlparse import urlunparse # Python2 import requests import requests_oauthlib import logging try: - import io # Python3 + from urllib.parse import urlunparse # Python3 except ImportError: - import StringIO as io # Python2 -try: - from configparser import ConfigParser # Python3 -except ImportError: - from ConfigParser import SafeConfigParser as ConfigParser # Python2 + from urlparse import urlunparse # Python2 + +from openphoto.objects import OpenPhotoObject +from openphoto.errors import * +import openphoto.config_files if sys.version < '3': - text_type = unicode # Python2 -else: - text_type = str # Python3 - -from .objects import OpenPhotoObject -from .errors import * - -if sys.version < '3': - # requests_oauth needs to decode to ascii for Python2 + text_type = unicode + # requests_oauth needs to decode to ascii for Python2 _oauth_decoding = "utf-8" else: - # requests_oauth needs to use (unicode) strings for Python3 - _oauth_decoding = None # Python3 + text_type = str + # requests_oauth needs to use (unicode) strings for Python3 + _oauth_decoding = None DUPLICATE_RESPONSE = {"code": 409, "message": "This photo already exists"} @@ -55,8 +45,8 @@ class OpenPhotoHttp: self._logger = logging.getLogger("openphoto") if host is None: - self.config_path = self._get_config_path(config_file) - config = self._read_config(self.config_path) + self._config_path = openphoto.config_files.get_config_path(config_file) + config = openphoto.config_files.read_config(self._config_path) self._host = config['host'] self._consumer_key = config['consumerKey'] self._consumer_secret = config['consumerSecret'] @@ -237,49 +227,3 @@ class OpenPhotoHttp: return [] else: return result - - @staticmethod - def _get_config_path(config_file): - config_path = os.getenv('XDG_CONFIG_HOME') - if not config_path: - config_path = os.path.join(os.getenv('HOME'), ".config") - if not config_file: - config_file = "default" - return os.path.join(config_path, "openphoto", config_file) - - def _read_config(self, config_file): - """ - Loads config data from the specified file. - If config_file doesn't exist, returns an empty authentication config for localhost. - """ - section = "DUMMY" - defaults = {'host': 'localhost', - 'consumerKey': '', 'consumerSecret': '', - 'token': '', 'tokenSecret':'', - } - # Insert an section header at the start of the config file, so ConfigParser can understand it - buf = io.StringIO() - buf.write('[%s]\n' % section) - with io.open(config_file, "r") as f: - buf.write(f.read()) - - buf.seek(0, os.SEEK_SET) - parser = ConfigParser() - parser.optionxform = str # Case-sensitive options - try: - parser.read_file(buf) # Python3 - except AttributeError: - parser.readfp(buf) # Python2 - - # Trim quotes - config = parser.items(section) - config = [(item[0].replace('"', ''), item[1].replace('"', '')) for item in config] - config = [(item[0].replace("'", ""), item[1].replace("'", "")) for item in config] - config = dict(config) - - # Apply defaults - for key in defaults: - if key not in config: - config[key] = defaults[key] - - return config diff --git a/tests/test_albums.py b/tests/test_albums.py index 88eeb19..dc7dc2b 100644 --- a/tests/test_albums.py +++ b/tests/test_albums.py @@ -1,11 +1,12 @@ try: - import unittest2 as unittest + import unittest2 as unittest # Python2.6 except ImportError: import unittest -import openphoto -from . import test_base -class TestAlbums(test_base.TestBase): +import openphoto +import tests.test_base + +class TestAlbums(tests.test_base.TestBase): testcase_name = "album API" def test_create_delete(self): diff --git a/tests/test_base.py b/tests/test_base.py index 86a27fe..db1b726 100644 --- a/tests/test_base.py +++ b/tests/test_base.py @@ -1,11 +1,12 @@ from __future__ import print_function import sys import os +import logging try: - import unittest2 as unittest + import unittest2 as unittest # Python2.6 except ImportError: import unittest -import logging + import openphoto def get_test_server_api(): diff --git a/tests/test_config.py b/tests/test_config.py index d0d21c2..fd2434f 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -1,9 +1,10 @@ -try: - import unittest2 as unittest -except ImportError: - import unittest import os import shutil +try: + import unittest2 as unittest # Python2.6 +except ImportError: + import unittest + import openphoto CONFIG_HOME_PATH = os.path.join("tests", "config") diff --git a/tests/test_framework.py b/tests/test_framework.py index d011914..6dc781e 100644 --- a/tests/test_framework.py +++ b/tests/test_framework.py @@ -1,12 +1,13 @@ +import logging try: - import unittest2 as unittest + import unittest2 as unittest # python2.6 except ImportError: import unittest -import logging -import openphoto -from . import test_base -class TestFramework(test_base.TestBase): +import openphoto +import tests.test_base + +class TestFramework(tests.test_base.TestBase): testcase_name = "framework" def setUp(self): @@ -23,7 +24,7 @@ class TestFramework(test_base.TestBase): def test_specified_api_version(self): # For all API versions >0, we get a generic hello world message - for api_version in range(1, test_base.get_test_server_api() + 1): + for api_version in range(1, tests.test_base.get_test_server_api() + 1): client = openphoto.OpenPhoto(config_file=self.config_file, api_version=api_version) result = client.get("hello.json") diff --git a/tests/test_photos.py b/tests/test_photos.py index 0772d86..fcd69b8 100644 --- a/tests/test_photos.py +++ b/tests/test_photos.py @@ -1,12 +1,13 @@ from __future__ import unicode_literals try: - import unittest2 as unittest + import unittest2 as unittest # Python2.6 except ImportError: import unittest -import openphoto -from . import test_base -class TestPhotos(test_base.TestBase): +import openphoto +import tests.test_base + +class TestPhotos(tests.test_base.TestBase): testcase_name = "photo API" def test_delete_upload(self): diff --git a/tests/test_tags.py b/tests/test_tags.py index a46f1cc..8fec176 100644 --- a/tests/test_tags.py +++ b/tests/test_tags.py @@ -1,13 +1,14 @@ try: - import unittest2 as unittest + import unittest2 as unittest # Python2.6 except ImportError: import unittest -import openphoto -from . import test_base -@unittest.skipIf(test_base.get_test_server_api() == 1, +import openphoto +import tests.test_base + +@unittest.skipIf(tests.test_base.get_test_server_api() == 1, "The tag API didn't work at v1 - see frontend issue #927") -class TestTags(test_base.TestBase): +class TestTags(tests.test_base.TestBase): testcase_name = "tag API" def test_create_delete(self, tag_id="create_tag"):