Commits

Mikhail Korobov  committed df8889f

bugfix for breaking vk.com changes (see #3, #4)

  • Participants
  • Parent commits 4cbfb8f

Comments (0)

Files changed (5)

 *.pyo
 *.orig
 *~
+stuff/
 
 #misc files
 pip-log.txt
 Changes
 =======
 
+dev (TBA)
+---------
+
+* bugfix for breaking vkontakte API updates.
+
+``simplejson`` is now required under python 2.6 (it was previously
+required only under python 2.5).
+
 1.3.2 (2012-05-19)
 ------------------
 
 
 [testenv]
 deps=
-    mock == 0.7.2
+    mock == 1.0.1
 
 commands=
     python vkontakte/tests.py
 
 [testenv:py25]
 deps=
-    mock == 0.7.2
+    mock == 1.0.1
+    simplejson
+
+[testenv:py26]
+deps=
+    mock == 1.0.1
     simplejson

File vkontakte/api.py

 import random
 import time
 import urllib
-import re
+import warnings
 from hashlib import md5
 from functools import partial
 try:
+    import simplejson as json
+except ImportError:
     import json
-except ImportError:
-    import simplejson as json
 from vkontakte import http
 
 API_URL = 'http://api.vk.com/api.php'
 
     return s # this can be number, etc.
 
+def _json_iterparse(response):
+    response = response.strip()
+    decoder = json.JSONDecoder(encoding="utf8", strict=False)
+    idx = 0
+    while idx < len(response):
+        obj, idx = decoder.raw_decode(response, idx)
+        yield obj
 
 def signature(api_secret, params):
     keys = sorted(params.keys())
                 'request_params': kwargs,
             })
 
-        data = json.loads(response, strict=False)
-        if "error" in data:
-            raise VKError(data["error"])
-        return data['response']
+        # there may be a response after errors
+        errors = []
+        for data in _json_iterparse(response):
+            if "error" in data:
+                errors.append(data["error"])
+            if "response" in data:
+                for error in errors:
+                    warnings.warn("%s" % error)
+                return data["response"]
+
+        raise VKError(errors[0])
 
     def __getattr__(self, name):
         '''

File vkontakte/tests.py

             '560b3f1e09ff65167b8dc211604fed2b'
         )
 
+class IterparseTest(unittest.TestCase):
+    def test_iterparse(self):
+        data = '{"error":{"error_code":8,"error_msg":"Invalid request: this auth method is obsolete, please use oauth. vk.com\/developers","request_params":[{"key":"sig","value":"97aasff03cc81d5db25de67893e207"},{"key":"uids","value":"1,2"},{"key":"timestamp","value":"1355095295"},{"key":"v","value":"3.0"},{"key":"fields","value":"education"},{"key":"format","value":"JSON"},{"key":"random","value":"937530097"},{"key":"method","value":"getProfiles"},{"key":"api_id","value":"3267523"}]}}{"error":{"error_code":8,"error_msg":"Invalid request: this auth method is obsolete, please use oauth. vk.com\/developers","request_params":[{"key":"sig","value":"97aasff03cc81d5db25de67893e207"},{"key":"uids","value":"1,2"},{"key":"timestamp","value":"1355095295"},{"key":"v","value":"3.0"},{"key":"fields","value":"education"},{"key":"format","value":"JSON"},{"key":"random","value":"937530097"},{"key":"method","value":"getProfiles"},{"key":"api_id","value":"3267523"}]}}{"response":[{"uid":1,"first_name":"Павел","last_name":"Дуров","university":1,"university_name":"СПбГУ","faculty":15,"faculty_name":"Филологический","graduation":2006},{"uid":2,"first_name":"Александра","last_name":"Владимирова"}]}'
+        parses = list(vkontakte.api._json_iterparse(data))
+        self.assertEqual(len(parses),  3)
+        assert "error" in parses[0]
+        assert "error" in parses[1]
+        self.assertEqual(parses[2]["response"][0]["first_name"], u"Павел")
+
+    def test_iterparse_edge(self):
+        data = '{"error": {"}{": "foo"}}{"foo":"bar"}'
+        parses = list(vkontakte.api._json_iterparse(data))
+        self.assertEqual(parses[0]["error"]["}{"], "foo")
+        self.assertEqual(parses[1]["foo"], "bar")
+
+
+
 class VkontakteMagicTest(unittest.TestCase):
 
     def setUp(self):