Skip to content

Commit

Permalink
Merge pull request #2 from TobiX/python-3-support
Browse files Browse the repository at this point in the history
Python 3 support
  • Loading branch information
neighbordog authored Oct 6, 2016
2 parents aefe53a + 21fd69e commit 029d263
Show file tree
Hide file tree
Showing 10 changed files with 376 additions and 9 deletions.
13 changes: 13 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
language: python
python:
- "2.7"
- "3.3"
- "3.4"
- "3.5"
cache: pip
sudo: false
# command to install dependencies
install:
- pip install tox-travis
# command to run tests
script: tox
23 changes: 15 additions & 8 deletions deviantart/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,15 @@
:copyright: (c) 2015 by Kevin Eichhorn
"""

from urllib import urlencode
from urllib2 import HTTPError
from sanction import Client, transport_headers
from __future__ import absolute_import

try:
from urllib import urlencode
from urllib2 import HTTPError
except ImportError:
from urllib.parse import urlencode
from urllib.error import HTTPError
from sanction import Client

from .deviation import Deviation
from .user import User
Expand Down Expand Up @@ -84,7 +90,7 @@ def auth(self, code="", refresh_token=""):
try:
self.oauth.request_token(grant_type="refresh_token", refresh_token=refresh_token)
self.refresh_token = self.oauth.refresh_token
except HTTPError, e:
except HTTPError as e:

if e.code == 401:
raise DeviantartError("Unauthorized: Please check your credentials (client_id and client_secret).")
Expand All @@ -94,7 +100,7 @@ def auth(self, code="", refresh_token=""):
try:
self.oauth.request_token(grant_type=self.standard_grant_type, redirect_uri=self.redirect_uri, code=code)
self.refresh_token = self.oauth.refresh_token
except HTTPError, e:
except HTTPError as e:

if e.code == 401:
raise DeviantartError("Unauthorized: Please check your credentials (client_id and client_secret).")
Expand All @@ -103,7 +109,7 @@ def auth(self, code="", refresh_token=""):
elif self.standard_grant_type == "client_credentials":
try:
self.oauth.request_token(grant_type=self.standard_grant_type)
except HTTPError, e:
except HTTPError as e:

if e.code == 401:
raise DeviantartError("Unauthorized: Please check your credentials (client_id and client_secret).")
Expand Down Expand Up @@ -1720,9 +1726,10 @@ def _req(self, endpoint, get_data=dict(), post_data=dict()):
request_parameter = endpoint

try:
response = self.oauth.request(request_parameter, data=urlencode(post_data, True))
encdata = urlencode(post_data, True).encode('utf-8')
response = self.oauth.request(request_parameter, data=encdata)
self._checkResponseForErrors(response)
except HTTPError, e:
except HTTPError as e:
raise DeviantartError(e)

return response
Expand Down
23 changes: 23 additions & 0 deletions tests/helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import os

from sanction.test import with_patched_client


def mock_response(name, code=200):
"""This decorator uses captured responses to mock server responses."""
testdir = os.path.dirname(__file__)
filename = os.path.join(testdir, 'mocks', "response_%s.json" % name)
with open(filename) as f:
data = "".join(f.readlines())
return with_patched_client(data, code)


def optional(run, deco):
"""This is a decorator which applies another decorator only if the
condition is true."""
if run:
return deco
else:
def do_nothing(func):
return func
return do_nothing
149 changes: 149 additions & 0 deletions tests/mocks/response_comments_siblings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
{
"has_less" : true,
"prev_offset" : -10,
"thread" : [
{
"posted" : "2016-01-03T09:23:44-0800",
"hidden" : null,
"user" : {
"username" : "EmptyPromiseFanFic",
"usericon" : "http://a.deviantart.net/avatars/e/m/emptypromisefanfic.jpg?2",
"type" : "regular",
"userid" : "E396E2C8-FBA3-3D3D-FBE2-AD7C16C02782"
},
"body" : "Devart at 8:00 in morning with bacon...",
"commentid" : "E99B1CEB-933F-B54D-ABC2-88FD0F66D421",
"replies" : 0,
"parentid" : null
},
{
"hidden" : null,
"posted" : "2016-01-02T19:50:29-0800",
"parentid" : null,
"user" : {
"usericon" : "http://a.deviantart.net/avatars/z/i/zirukurt01.jpg?3",
"username" : "zirukurt01",
"type" : "regular",
"userid" : "BE1B8A51-9B53-3ED4-78D9-7A6CDDDFEF6F"
},
"commentid" : "004396F2-6446-106B-C847-4024B71F869C",
"body" : "No wonder people rarely complain about Core on December.",
"replies" : 0
},
{
"posted" : "2016-01-02T11:16:08-0800",
"hidden" : null,
"commentid" : "166286B7-98BD-B4DE-A55D-36C1F2B57C1B",
"body" : "<a class=\"external\" href=\"http://www.deviantart.com/users/outgoing?http://poo2two.tumblr.com/post/136474330486\">poo2two.tumblr.com/post/136474&hellip;</a><br /><br />A little collection of my little man over the last two weeks, plus more can be found in my \"Henry Jensen\" tag here:<br /><br /><a class=\"external\" href=\"http://www.deviantart.com/users/outgoing?http://poo2two.tumblr.com/tagged/Henry-Jensen\">poo2two.tumblr.com/tagged/Henr&hellip;</a>",
"replies" : 3,
"user" : {
"username" : "pootwo",
"usericon" : "http://a.deviantart.net/avatars/p/o/pootwo.png?2",
"type" : "regular",
"userid" : "05D7BC94-908E-1BE5-0FC5-AFA900B7B36B"
},
"parentid" : null
},
{
"parentid" : null,
"user" : {
"type" : "regular",
"userid" : "BE1B8A51-9B53-3ED4-78D9-7A6CDDDFEF6F",
"username" : "zirukurt01",
"usericon" : "http://a.deviantart.net/avatars/z/i/zirukurt01.jpg?3"
},
"body" : "Visiting wasted accounts?<br />why not dead/abandoned accounts?<br /><a target=\"_self\" href=\"http://gbt.deviantart.com/\" ><img class=\"avatar\" width=\"50\" height=\"50\" src=\"http://a.deviantart.net/avatars/g/b/gbt.gif\" alt=\":icongbt:\" title=\"GBT\" /></a><a target=\"_self\" href=\"http://purestevil.deviantart.com/\" ><img class=\"avatar\" width=\"50\" height=\"50\" src=\"http://a.deviantart.net/avatars/default.gif\" alt=\":iconpurestevil:\" title=\"purestevil\" /></a>",
"commentid" : "01C924B6-2471-F54A-F9C3-DA4C75BF95A7",
"replies" : 0,
"hidden" : null,
"posted" : "2016-01-02T06:55:06-0800"
},
{
"user" : {
"username" : "isohak",
"usericon" : "http://a.deviantart.net/avatars/i/s/isohak.png?10",
"type" : "regular",
"userid" : "19385BF8-B992-2ECD-7CD2-5E3CF6D15573"
},
"replies" : 0,
"body" : "<a href=\"http://www.deviantart.com/users/outgoing?https://youtu.be/zPyjIvp2tm0\"><a class=\"external\" href=\"http://www.deviantart.com/users/outgoing?https://youtu.be/zPyjIvp2tm0\">youtu.be/zPyjIvp2tm0</a></a><br />Speed paint <img src=\"http://e.deviantart.net/emoticons/b/biggrin.gif\" width=\"15\" height=\"15\" alt=\":D\" data-embed-type=\"emoticon\" data-embed-id=\"366\" title=\":D (Big Grin)\"/>",
"commentid" : "1672D2F9-3204-8656-6ABA-D8FCE3E00F6D",
"parentid" : null,
"posted" : "2016-01-02T00:52:45-0800",
"hidden" : null
},
{
"replies" : 0,
"body" : "<a class=\"external\" href=\"http://www.deviantart.com/users/outgoing?https://www.youtube.com/watch?v=NhP-OUt1Eos\">www.youtube.com/watch?v=NhP-OU&hellip;</a><br />If you're an European, Don't be offended when you see this video above.",
"commentid" : "25B1CAE9-80AE-DC2A-C8C9-3DDC192A3F4E",
"user" : {
"usericon" : "http://a.deviantart.net/avatars/z/i/zirukurt01.jpg?3",
"username" : "zirukurt01",
"userid" : "BE1B8A51-9B53-3ED4-78D9-7A6CDDDFEF6F",
"type" : "regular"
},
"parentid" : null,
"posted" : "2016-01-01T18:32:03-0800",
"hidden" : null
},
{
"user" : {
"type" : "regular",
"userid" : "2B00B611-3A29-9B84-F65F-86908B930483",
"usericon" : "http://a.deviantart.net/avatars/x/x/xxmidnightderexx.gif?8",
"username" : "xXMidnightDereXx"
},
"body" : "Can you reactivate (is that what it's called?) my friend Katie623DA's account on May 7, 2016? Cause that's when her 13th birthday is. Kay, thanks.",
"replies" : 1,
"commentid" : "F4DB39C5-8190-2133-3CFC-07E79719D886",
"parentid" : null,
"posted" : "2016-01-01T17:27:06-0800",
"hidden" : null
},
{
"user" : {
"userid" : "CD534E09-E111-93F3-ACFB-A17E7A5FD73F",
"type" : "beta",
"username" : "BillyNikoll",
"usericon" : "http://a.deviantart.net/avatars/b/i/billynikoll.gif?2"
},
"body" : "<span class=\"shadow-holder\" data-embed-type=\"deviation\" data-embed-id=\"2383397049456835\" data-embed-format=\"thumb\"><span class=\"tt-fh-tc is-grid\" style=\"width: 300px; \n \" ><span class=\"shadow mild\" ><a class=\"thumb\" href=\"http://sta.sh/0ngudhlrav7\" title=\"IMG 1039ddd by BillyNikoll, Jan 1, 2016\" data-super-img=\"http://orig08.deviantart.net/89cc/f/2016/001/3/5/img_1039ddd_by_billynikoll-d9mc5dl.jpg\" data-super-width=\"5184\" data-super-height=\"3456\" data-super-transparent=\"false\"><i></i><img onerror=\"autobob.error(event)\" onload=\"autobob.load(event)\" width=\"300\" height=\"200\" alt=\"IMG 1039ddd by BillyNikoll\" src=\"http://t02.deviantart.net/7TCZ4UEX22nNoTOPn0GJIql3rvw=/300x200/filters:fixed_height(100,100):origin()/pre04/d914/th/pre/i/2016/001/6/d/img_1039ddd_by_billynikoll-d9mc5dl.jpg\" data-src=\"http://t02.deviantart.net/7TCZ4UEX22nNoTOPn0GJIql3rvw=/300x200/filters:fixed_height(100,100):origin()/pre04/d914/th/pre/i/2016/001/6/d/img_1039ddd_by_billynikoll-d9mc5dl.jpg\"></a></span><!-- ^TTT --></span><span class=\"details\" ></span><!-- TTT$ --></span> ",
"replies" : 0,
"commentid" : "33A74620-CA02-EB93-4233-46BC03B71DAD",
"parentid" : null,
"posted" : "2016-01-01T11:55:49-0800",
"hidden" : null
},
{
"commentid" : "5F8BE9B9-BACE-1D41-4590-016FE5467AA8",
"body" : "At my funeral, I want them to play Kraftwerk, while some guy eats fried chicken in the middle of the room. People will be far too baffled, and/or terrified to be sad!",
"replies" : 1,
"user" : {
"type" : "regular",
"userid" : "689A4C8C-2AB7-F51F-7D39-7185D1B65D08",
"usericon" : "http://a.deviantart.net/avatars/s/h/sherberttcat.png?2",
"username" : "SherbertTCat"
},
"parentid" : null,
"posted" : "2015-12-31T23:49:18-0800",
"hidden" : null
},
{
"user" : {
"usericon" : "http://a.deviantart.net/avatars/z/i/zirukurt01.jpg?3",
"username" : "zirukurt01",
"userid" : "BE1B8A51-9B53-3ED4-78D9-7A6CDDDFEF6F",
"type" : "regular"
},
"body" : "[Hidden by Commenter]",
"commentid" : "34DA2CFB-DE13-6EF5-B487-BAEBC0D6A507",
"replies" : 3,
"parentid" : null,
"posted" : "2015-12-31T23:25:45-0800",
"hidden" : "hidden_by_commenter"
}
],
"context" : [],
"has_more" : true,
"next_offset" : 10
}
58 changes: 58 additions & 0 deletions tests/mocks/response_deviation.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{
"title" : "Jark Promo",
"deviationid" : "234546F5-C9D1-A9B1-D823-47C4E3D2DB95",
"download_filesize" : 58152,
"category_path" : "darelated/deviousfun",
"is_mature" : false,
"is_deleted" : false,
"thumbs" : [
{
"transparency" : false,
"height" : 124,
"width" : 150,
"src" : "http://t02.deviantart.net/xsBzNtUchXtyCS5LC5BpXWElY4A=/fit-in/150x150/filters:no_upscale():origin()/pre08/9ee5/th/pre/i/2005/098/2/6/jark_promo_by_devart.jpg"
},
{
"src" : "http://t05.deviantart.net/NpNV-_DQUBg2I5QHXD-5gpnYNaQ=/300x200/filters:fixed_height(100,100):origin()/pre08/9ee5/th/pre/i/2005/098/2/6/jark_promo_by_devart.jpg",
"height" : 200,
"width" : 242,
"transparency" : false
},
{
"height" : 248,
"width" : 300,
"transparency" : false,
"src" : "http://t13.deviantart.net/af4hHtZ6_82ii-tqOilj8ZjBjzg=/fit-in/300x900/filters:no_upscale():origin()/pre08/9ee5/th/pre/i/2005/098/2/6/jark_promo_by_devart.jpg"
}
],
"preview" : {
"transparency" : false,
"width" : 556,
"height" : 459,
"src" : "http://img04.deviantart.net/db06/i/2005/098/2/6/jark_promo_by_devart.jpg"
},
"author" : {
"type" : "admin",
"usericon" : "http://a.deviantart.net/avatars/d/e/devart.png?2",
"username" : "devart",
"userid" : "E2C3A89D-9A7B-3FA1-BBF5-5F8841ABB8D7"
},
"url" : "http://devart.deviantart.com/art/Jark-Promo-15972403",
"stats" : {
"comments" : 0,
"favourites" : 209
},
"is_downloadable" : true,
"published_time" : 1110510523,
"printid" : null,
"allows_comments" : false,
"category" : "Devious Fun",
"content" : {
"filesize" : 58152,
"transparency" : false,
"height" : 459,
"width" : 556,
"src" : "http://img04.deviantart.net/db06/i/2005/098/2/6/jark_promo_by_devart.jpg"
},
"is_favourited" : false
}
6 changes: 6 additions & 0 deletions tests/mocks/response_token.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"access_token": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"expires_in": 3600,
"status": "success",
"token_type": "Bearer"
}
29 changes: 29 additions & 0 deletions tests/mocks/response_user_profile_devart.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"artist_level": null,
"artist_specialty": null,
"bio": "",
"country": "Unknown",
"countryid": 0,
"cover_photo": "",
"is_watching": false,
"last_status": null,
"profile_pic": null,
"profile_url": "http://devart.deviantart.com",
"real_name": "DeviantArt System Bot",
"stats": {
"profile_comments": 209961,
"profile_pageviews": 2076161,
"user_comments": 0,
"user_deviations": 9,
"user_favourites": 0
},
"tagline": "",
"user": {
"type": "admin",
"usericon": "http://a.deviantart.net/avatars/d/e/devart.png?2",
"userid": "E2C3A89D-9A7B-3FA1-BBF5-5F8841ABB8D7",
"username": "devart"
},
"user_is_artist": false,
"website": "http://www.deviantart.com"
}
13 changes: 12 additions & 1 deletion tests/test_api.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,32 @@
from __future__ import absolute_import

import unittest
import deviantart
from api_credentials import CLIENT_ID, CLIENT_SECRET
from .helpers import mock_response, optional
from .api_credentials import CLIENT_ID, CLIENT_SECRET


class ApiTest(unittest.TestCase):

@optional(CLIENT_ID == "", mock_response('token'))
def setUp(self):
self.da = deviantart.Api(CLIENT_ID, CLIENT_SECRET)

@optional(CLIENT_ID == "", mock_response('user_profile_devart'))
def test_get_user(self):
user = self.da.get_user("devart")
self.assertEqual("devart", user.username)
self.assertEqual("devart", repr(user))

@optional(CLIENT_ID == "", mock_response('deviation'))
def test_get_deviation(self):
deviation = self.da.get_deviation("234546F5-C9D1-A9B1-D823-47C4E3D2DB95")
self.assertEqual("234546F5-C9D1-A9B1-D823-47C4E3D2DB95", deviation.deviationid)
self.assertEqual("234546F5-C9D1-A9B1-D823-47C4E3D2DB95", repr(deviation))

@optional(CLIENT_ID == "", mock_response('comments_siblings'))
def test_get_comment(self):
comments = self.da.get_comments("siblings", commentid="E99B1CEB-933F-B54D-ABC2-88FD0F66D421")
comment = comments['thread'][0]
self.assertEqual("E99B1CEB-933F-B54D-ABC2-88FD0F66D421", comment.commentid)
self.assertEqual("E99B1CEB-933F-B54D-ABC2-88FD0F66D421", repr(comment))
Loading

0 comments on commit 029d263

Please sign in to comment.