From 9917fe1e6eaa082ff09882db68327d47102cf2ba Mon Sep 17 00:00:00 2001 From: Tim Shi Date: Mon, 5 Mar 2012 22:26:28 -0800 Subject: [PATCH 1/9] added support for handling retrieval of parse objects with files --- __init__.py | 20 +++++++++++++++++--- __init__.pyc | Bin 0 -> 10792 bytes 2 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 __init__.pyc diff --git a/__init__.py b/__init__.py index e01657c..93133ef 100644 --- a/__init__.py +++ b/__init__.py @@ -17,7 +17,7 @@ import datetime import collections -API_ROOT = 'https://api.parse.com/1/classes' +API_ROOT = 'https://api.parse.com/1' APPLICATION_ID = '' MASTER_KEY = '' @@ -28,8 +28,13 @@ class ParseBinaryDataWrapper(str): class ParseBase(object): - def _executeCall(self, uri, http_verb, data=None): - url = API_ROOT + uri + def _executeCall(self, uri, http_verb, data=None, apiType=None): + url = API_ROOT + if apiType: + url = url + apiType + else : + url = url + '/classes' + url = url + uri request = urllib2.Request(url, data) @@ -129,6 +134,8 @@ def _convertFromParseType(self, prop): value = self._ISO8601ToDatetime(value['iso']) elif value['__type'] == 'Bytes': value = ParseBinaryDataWrapper(base64.b64decode(value['base64'])) + elif value['__type'] == 'File': + value = ParseFile(value['name'], value['url']) else: raise Exception('Invalid __type.') @@ -252,4 +259,11 @@ def _fetch(self, single_result=False): return ParseObject(self._class_name, response_dict) else: return [ParseObject(self._class_name, result) for result in response_dict['results']] + +class ParseFile(ParseObject): + def __init__(self, file_name, url): + self.file_name = file_name + self.url = url + + diff --git a/__init__.pyc b/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1432f83087b71db3c5a3e7786c1bdbc7bf007ae6 GIT binary patch literal 10792 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 literal 0 HcmV?d00001 From 0488cf5c996f7ab2f7d9f595a8cdf66a6819c659 Mon Sep 17 00:00:00 2001 From: Tim Shi Date: Tue, 6 Mar 2012 00:11:12 -0800 Subject: [PATCH 2/9] handles files and geopoints --- __init__.py | 16 +++++++++++++++- __init__.pyc | Bin 10792 -> 11267 bytes 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/__init__.py b/__init__.py index 93133ef..3e2c7c8 100644 --- a/__init__.py +++ b/__init__.py @@ -121,7 +121,14 @@ def _convertToParseType(self, prop): elif type(value) == ParseBinaryDataWrapper: value = {'__type': 'Bytes', 'base64': base64.b64encode(value)} - + elif type(value) == ParseFile: + value = {'__type': 'File', + 'name': value.file_name, + 'url': value.url} + elif type(value) == ParseGeoPoint: + value = {'__type': 'GeoPoint', + 'latitude': value._latitude, + 'longitude': value._longitude} return (key, value) def _convertFromParseType(self, prop): @@ -136,6 +143,8 @@ def _convertFromParseType(self, prop): value = ParseBinaryDataWrapper(base64.b64decode(value['base64'])) elif value['__type'] == 'File': value = ParseFile(value['name'], value['url']) + elif value['__type'] == 'GeoPoint': + value = ParseGeoPoint(value['latitude'], value['longitude']) else: raise Exception('Invalid __type.') @@ -265,5 +274,10 @@ def __init__(self, file_name, url): self.file_name = file_name self.url = url +class ParseGeoPoint(ParseObject): + def __init__(self, latitude, longitude): + self._latitude = latitude + self._longitude = longitude + diff --git a/__init__.pyc b/__init__.pyc index 1432f83087b71db3c5a3e7786c1bdbc7bf007ae6..0c0f488ebd788f94ffe43ebc54dbc4034521343f 100644 GIT binary patch delta 864 zcmaJgN!v_BELuuE z^`MrgV0-YQh#o@@-t<)PAl3!(pkndlpTlN3E`YGx&;nod$mM&8mO?#+2zXh~&9%j&NLnDt&~6R@Q<#O$>Lt=){x z)CxYv*bON9AFx3P1ZLP>s0MDMoC;oJRagk7QQjW9>D=J-IwhxzCu=W54;gz5Q}X^m z21~?f5bi@T8xV|aQH2G0n9ae_w!_k&5j+d;n!#dec8B4D~Hi_@L6!FP+7L^*Oi(^Bw0!4UHe5zw^+F+lHz& zCNDs>EpNl;g`&V#rRQ(IPJRd1G2s(PN;@no&&3pKi|}OgZe{@M8e>bfOI`bzmC9*J z+)Ho*o^|gG6iM_WnClQq!=_d;%6t^$$OX|r%U8G+*#@s8-UJ__&^(2T2z^<-ta56c z7YL{YPL=rxfdRdtqL@VS5sXI_w{b&6U)y4 delta 762 zcmaKqO=uHQ5XUpS-EE^yOpV!ONo%m~^v=?jn^O z6ub#yWvJAPc<`W5y(}W=MGw-0JqSH`(1S-0LQoH$D$W=WBE((hxBvI%7W?r{bTN62cH9IZ0Nqj+B9I}|$Wq|fw+#R+`FCRgu!zgrV>p8&@q6$9 zKgREqZX|BQ6Wpv%k)F|)f{|bkSxAie8~SsAm-sAsBzlfYo7}R9F-{P0OR5g9@p|fb z8?PhV-YRB#58{f}TSzK-nC>0IUFrYVDS6g9zDl>PBRkf6Iwyt? zGoz6iI{2@VO87H#MJdtd2fUg+)^ba^XU$8{h0e~K+9U;Z0$nGbT?I43xh{tD2{?(H`VLp%8kDF2=n From 01c8e04a783f66521d3a848c7723de0a302446d5 Mon Sep 17 00:00:00 2001 From: Tim Shi Date: Tue, 6 Mar 2012 00:13:43 -0800 Subject: [PATCH 3/9] added gitignore --- .gitignore | 1 + __init__.pyc | Bin 11267 -> 11521 bytes 2 files changed, 1 insertion(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7e99e36 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.pyc \ No newline at end of file diff --git a/__init__.pyc b/__init__.pyc index 0c0f488ebd788f94ffe43ebc54dbc4034521343f..a67284dfa695ebc753b5579f633cb437dfdd2867 100644 GIT binary patch delta 1318 zcmah}OGs2v7(VAtV~sj9ckVRTCMVzJ&FNu8Qb7+5pQVjQu?K;QbJfx79i2J7iylUc zB3k?uxyV%nLPQ}wb_GR2tDqJxgj%?15fKtWWc2@cdPBwVf9F5{>-^_C|DDm@r}k#K zX1&?xp4`rQ=~v1)O#5s26cnl(_&DrQ*PO7JWbBxWjdCVEY*1mT8J2Ldcn*sztO^|i z*({!$(a`2)RmWY-uKFb_*U4JUDa-dG%gf^aOcvVIOcoxb&{@3-Ycm3ju@(te)%JyQ z9_n=o%XAdGd&m@FSQ?Bfh973tO+IXlu~>I1ZBh_a8^P7m``uJ;CS%EjEuElFt6L`I z{XdKM)eK_Hfjk&Pl09VLRYn8WbG`@EH+-SaVK94?0p z-VP5!Q+y1r=o7pPYVyYT1Wf0RqkeSJMSd4@!i_oY7%k`k(FL91OP)MW(4%_1qGNI{ ze2??Ta3_CT$V9*4q9CU~=c;WGh}irYoQ!P$tKV{2@;MY0Y=#RI&1T?mabw0!LzlV! zutW1O?%%+cl7>IsBaV9n-EYxd041f*-Meu29zK??=V_=cJIX&y-YBc)PNpDoMUY@0 z%q^|TOOdK0NP5YnGaPAg5So@9a;MSq37#%nThm8T{R9bu0fIpS3qjJCQP*vyO+mL1 z)T^M51T`WK5TxOqG34$*^%2}GFHyt}7+T(|i)M1t9RKp*&Cq3xz);2c01dCoaTJM; zEG}9oDIj)IQtW3Eyb7k^R{lJ$gI#e>r)dxU%yRx;#1ZgC7x5k_kFLw1Hokor*p>w^ MqEYu5y;*mE1&n3~&j0`b delta 1138 zcmah{T}YE*6#m}L&)VkCe%zm?>WzV{=PF2o;;Rq z{+4U~u{4+cBHy$ifx}e}KlA-e2d{k(Yk(emeV!zZo1}5G6gNpnR2yVDdQ7SXW*z&W z#(8&Vk%T{%V{$Sp{_V_-Si+pS`(1S= zJce9;I;LGgI-a`JvWz6GQg06NE;A{$p_p8#FQ^6KP)pMJ7`-Dk8r74%zDPuz8Pe)h z8`^jaOc%5_iCok}(UG*)rVWM$lPMuAXlWUXX+t78m{O@q?j~p>Xea1^kkaSfi|PbQ z`gf-l*rg9eK`AxEP4@z8L#EDV;IX2zPWYg_V%K4@@E!|8vS^0g0dw)JEleT31VK1o zG$A*lItLA&4qGP~DGd+970(Te)8ew&ExEjV-e2;Fu|;@O+FTq#ziK8DRVk?6RCGWy zicD-5G-+*k32v7ia&M&aC_SQH5-x+Li)Uy_Qv``Q;C@*nJSflm_bZE_w7Sriq1n4- z^n`f6IeN&qW%Pv5Ucx)yf1{xTtNY*}S zKYd8KAMfuW;4gMdd z2F+arN5L0pDjXnHK@i&z293>1^AQ*bjLEpU(s%e6Xgqk5STTZL0*xR}kU$WWs5Ppm zHBRktDwjq4l? zR}Zrs&}*(b&Z5i4a35$~*^G0z5R5~fv)uk?+4x~}@h+MWysf^baJ<^rpQsLUpN5>; dB6b|AYIoVFG){pr+LT9!mD(ElqSB?vzW{j}?koTR From 216a5a94a988fb02fd9a4e7d1e23de96b2d7511a Mon Sep 17 00:00:00 2001 From: Tim Shi Date: Tue, 6 Mar 2012 00:14:28 -0800 Subject: [PATCH 4/9] removed pyc --- __init__.pyc | Bin 11521 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 __init__.pyc diff --git a/__init__.pyc b/__init__.pyc deleted file mode 100644 index a67284dfa695ebc753b5579f633cb437dfdd2867..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11521 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 aJc3W%^y?O2?h3id{N$<0dy`iuhyDX!zngOa From 5b81958c644cd94d716ee79c32f8931343bc224a Mon Sep 17 00:00:00 2001 From: Tim Shi Date: Tue, 6 Mar 2012 22:18:48 -0800 Subject: [PATCH 5/9] starting parseuser implementation --- __init__.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/__init__.py b/__init__.py index 3e2c7c8..d7f6dcc 100644 --- a/__init__.py +++ b/__init__.py @@ -263,7 +263,7 @@ def _fetch(self, single_result=False): uri = '/%s?%s' % (self._class_name, urllib.urlencode(options)) response_dict = self._executeCall(uri, 'GET') - + print response_dict if single_result: return ParseObject(self._class_name, response_dict) else: @@ -279,5 +279,11 @@ def __init__(self, latitude, longitude): self._latitude = latitude self._longitude = longitude +class ParseUser(ParseObject): + def __init__(self, username, email): + self.username = username + self.email = email + self.session_token = None + From 643d3ba08d1370736cf000482f678eb0c830cc94 Mon Sep 17 00:00:00 2001 From: Tim Shi Date: Tue, 6 Mar 2012 23:27:27 -0800 Subject: [PATCH 6/9] got log in working --- __init__.py | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/__init__.py b/__init__.py index d7f6dcc..11d58d1 100644 --- a/__init__.py +++ b/__init__.py @@ -36,6 +36,7 @@ def _executeCall(self, uri, http_verb, data=None, apiType=None): url = url + '/classes' url = url + uri + print url request = urllib2.Request(url, data) request.add_header('Content-type', 'application/json') @@ -45,7 +46,7 @@ def _executeCall(self, uri, http_verb, data=None, apiType=None): request.add_header("Authorization", auth_header) request.get_method = lambda: http_verb - + print request # TODO: add error handling for server response response = urllib2.urlopen(request) response_body = response.read() @@ -263,7 +264,6 @@ def _fetch(self, single_result=False): uri = '/%s?%s' % (self._class_name, urllib.urlencode(options)) response_dict = self._executeCall(uri, 'GET') - print response_dict if single_result: return ParseObject(self._class_name, response_dict) else: @@ -280,10 +280,40 @@ def __init__(self, latitude, longitude): self._longitude = longitude class ParseUser(ParseObject): - def __init__(self, username, email): + def __init__(self, username=None, email=None, session_token=None): self.username = username self.email = email - self.session_token = None + self.session_token = session_token + + def login(self, username, password): + + + + url = API_ROOT + '/login?' + + + + + encoded_args = urllib.urlencode({"username": username, "password": password}) + + url = url + encoded_args + + request = urllib2.Request(url) + + # we could use urllib2's authentication system, but it seems like overkill for this + auth_header = "Basic %s" % base64.b64encode('%s:%s' % (APPLICATION_ID, MASTER_KEY)) + request.add_header("Authorization", auth_header) + + response = urllib2.urlopen(request) + response_body = response.read() + response_dict = json.loads(response_body) + + self.username = response_dict['username'] + self.email = response_dict['email'] + self.session_token = response_dict['sessionToken'] + self._object_id = response_dict['objectId'] + + return self From adc804fdad2bc1e5647fd24c17e4d404c65fda0a Mon Sep 17 00:00:00 2001 From: Tim Shi Date: Thu, 29 Mar 2012 12:19:07 -0700 Subject: [PATCH 7/9] added support for datetime queries --- __init__.py | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/__init__.py b/__init__.py index 11d58d1..d10b427 100644 --- a/__init__.py +++ b/__init__.py @@ -16,6 +16,7 @@ import json import datetime import collections +import re API_ROOT = 'https://api.parse.com/1' @@ -36,7 +37,6 @@ def _executeCall(self, uri, http_verb, data=None, apiType=None): url = url + '/classes' url = url + uri - print url request = urllib2.Request(url, data) request.add_header('Content-type', 'application/json') @@ -46,7 +46,7 @@ def _executeCall(self, uri, http_verb, data=None, apiType=None): request.add_header("Authorization", auth_header) request.get_method = lambda: http_verb - print request + # TODO: add error handling for server response response = urllib2.urlopen(request) response_body = response.read() @@ -259,11 +259,15 @@ def _fetch(self, single_result=False): if self._where: # JSON encode WHERE values where = json.dumps(self._where) + where = where.translate(None, '\\') + where = re.sub('"{', '{', where) + where = re.sub('}"', '}', where) options.update({'where': where}) - + uri = '/%s?%s' % (self._class_name, urllib.urlencode(options)) response_dict = self._executeCall(uri, 'GET') + if single_result: return ParseObject(self._class_name, response_dict) else: @@ -304,14 +308,20 @@ def login(self, username, password): auth_header = "Basic %s" % base64.b64encode('%s:%s' % (APPLICATION_ID, MASTER_KEY)) request.add_header("Authorization", auth_header) - response = urllib2.urlopen(request) - response_body = response.read() - response_dict = json.loads(response_body) + try: + response = urllib2.urlopen(request) + response_body = response.read() + response_dict = json.loads(response_body) - self.username = response_dict['username'] - self.email = response_dict['email'] - self.session_token = response_dict['sessionToken'] - self._object_id = response_dict['objectId'] + + + self.username = response_dict['username'] + self.email = response_dict['email'] + self.session_token = response_dict['sessionToken'] + self._object_id = response_dict['objectId'] + except urllib2.HTTPError: + self.session_token = None + pass return self From aaf554524dd1c987fae47d96c9fc4a64c8eb541e Mon Sep 17 00:00:00 2001 From: Tim Shi Date: Sat, 14 Apr 2012 22:38:14 -0700 Subject: [PATCH 8/9] working --- __init__.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/__init__.py b/__init__.py index d10b427..f20011f 100644 --- a/__init__.py +++ b/__init__.py @@ -71,6 +71,12 @@ def __init__(self, class_name, attrs_dict=None): if attrs_dict: self._populateFromDict(attrs_dict) + def __str__(self): + return self._object_id + + def __unicode__(self): + return self._object_id + def objectId(self): return self._object_id @@ -146,6 +152,8 @@ def _convertFromParseType(self, prop): value = ParseFile(value['name'], value['url']) elif value['__type'] == 'GeoPoint': value = ParseGeoPoint(value['latitude'], value['longitude']) + # elif value['__type'] == "PFUser" + # value = ParseUser() else: raise Exception('Invalid __type.') @@ -278,17 +286,32 @@ def __init__(self, file_name, url): self.file_name = file_name self.url = url + def __unicode__(self): + return self.url + + def __str__(self): + return self.url + class ParseGeoPoint(ParseObject): def __init__(self, latitude, longitude): self._latitude = latitude self._longitude = longitude + def __unicode__(self): + return self._latitude + ", " + self._longitude + + def __str__(self): + return "%f, %f" % (self._latitude, self._longitude) + class ParseUser(ParseObject): def __init__(self, username=None, email=None, session_token=None): self.username = username self.email = email self.session_token = session_token + def __unicode__(self): + return username + def login(self, username, password): From b845fd088bc9c25a6e3b50d06f1b488a11dcbff2 Mon Sep 17 00:00:00 2001 From: Tim Shi Date: Mon, 30 Apr 2012 11:34:17 -0700 Subject: [PATCH 9/9] fb partially done --- __init__.py | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/__init__.py b/__init__.py index f20011f..74fe695 100644 --- a/__init__.py +++ b/__init__.py @@ -143,7 +143,10 @@ def _convertFromParseType(self, prop): if type(value) == dict and value.has_key('__type'): if value['__type'] == 'Pointer': - value = ParseQuery(value['className']).get(value['objectId']) + try: + value = ParseQuery(value['className']).get(value['objectId']) + except urllib2.HTTPError: + pass elif value['__type'] == 'Date': value = self._ISO8601ToDatetime(value['iso']) elif value['__type'] == 'Bytes': @@ -312,6 +315,41 @@ def __init__(self, username=None, email=None, session_token=None): def __unicode__(self): return username + def facebookLogin(self, userID, access_token, expiration_date): + url = API_ROOT + '/users?' + + encoded_args = urllib.urlencode({"authData": {"facebook": {"id": userID, + "access_token": access_token, + "expiration_date": "2020-01-01'T'12:12:12.111'Z'"}}}) + + + url = url + encoded_args + print url + request = urllib2.Request(url) + + # we could use urllib2's authentication system, but it seems like overkill for this + auth_header = "Basic %s" % base64.b64encode('%s:%s' % (APPLICATION_ID, MASTER_KEY)) + request.add_header("Authorization", auth_header) + try: + print 'before response' + response = urllib2.urlopen(request) + print response + response_body = response.read() + response_dict = json.loads(response_body) + + + + self.username = response_dict['username'] + self.email = response_dict['email'] + self.session_token = response_dict['sessionToken'] + self._object_id = response_dict['objectId'] + except urllib2.HTTPError: + print 'http error' + self.session_token = None + pass + + return self + def login(self, username, password):