Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
ParsePy
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenEdx
ParsePy
Commits
c6106771
Commit
c6106771
authored
Jul 17, 2014
by
Roman Krejcik
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Python3 support
parent
cd9ef16a
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
43 additions
and
45 deletions
+43
-45
parse_rest/connection.py
+7
-10
parse_rest/datatypes.py
+15
-12
parse_rest/installation.py
+3
-3
parse_rest/query.py
+8
-14
parse_rest/tests.py
+0
-0
parse_rest/user.py
+4
-4
setup.py
+6
-2
No files found.
parse_rest/connection.py
View file @
c6106771
...
@@ -11,18 +11,13 @@
...
@@ -11,18 +11,13 @@
# You should have received a copy of the GNU General Public License
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program. If not, see <http://www.gnu.org/licenses/>.
try
:
from
six.moves.urllib.request
import
Request
,
urlopen
from
urllib2
import
Request
,
urlopen
,
HTTPError
from
six.moves.urllib.error
import
HTTPError
from
urllib
import
urlencode
from
six.moves.urllib.parse
import
urlencode
except
ImportError
:
# is Python3
from
urllib.request
import
Request
,
urlopen
from
urllib.error
import
HTTPError
from
urllib.parse
import
urlencode
import
json
import
json
import
core
from
parse_rest
import
core
API_ROOT
=
'https://api.parse.com/1'
API_ROOT
=
'https://api.parse.com/1'
ACCESS_KEYS
=
{}
ACCESS_KEYS
=
{}
...
@@ -79,6 +74,8 @@ class ParseBase(object):
...
@@ -79,6 +74,8 @@ class ParseBase(object):
if
http_verb
==
'GET'
and
data
:
if
http_verb
==
'GET'
and
data
:
url
+=
'?
%
s'
%
urlencode
(
kw
)
url
+=
'?
%
s'
%
urlencode
(
kw
)
data
=
None
data
=
None
else
:
data
=
data
.
encode
(
'utf-8'
)
request
=
Request
(
url
,
data
,
headers
)
request
=
Request
(
url
,
data
,
headers
)
request
.
add_header
(
'Content-type'
,
'application/json'
)
request
.
add_header
(
'Content-type'
,
'application/json'
)
...
@@ -101,7 +98,7 @@ class ParseBase(object):
...
@@ -101,7 +98,7 @@ class ParseBase(object):
}
.
get
(
e
.
code
,
core
.
ParseError
)
}
.
get
(
e
.
code
,
core
.
ParseError
)
raise
exc
(
e
.
read
())
raise
exc
(
e
.
read
())
return
json
.
loads
(
response
.
read
())
return
json
.
loads
(
response
.
read
()
.
decode
(
'utf-8'
)
)
@classmethod
@classmethod
def
GET
(
cls
,
uri
,
**
kw
):
def
GET
(
cls
,
uri
,
**
kw
):
...
...
parse_rest/datatypes.py
View file @
c6106771
...
@@ -10,12 +10,14 @@
...
@@ -10,12 +10,14 @@
#
#
# You should have received a copy of the GNU General Public License
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from
__future__
import
unicode_literals
import
base64
import
base64
import
datetime
import
datetime
import
six
from
connection
import
API_ROOT
,
ParseBase
from
parse_rest.
connection
import
API_ROOT
,
ParseBase
from
query
import
QueryManager
from
parse_rest.
query
import
QueryManager
class
ParseType
(
object
):
class
ParseType
(
object
):
...
@@ -94,7 +96,7 @@ class Pointer(ParseType):
...
@@ -94,7 +96,7 @@ class Pointer(ParseType):
# also circular refs through more object are now ignored, in fact lazy loaded references will be best solution
# also circular refs through more object are now ignored, in fact lazy loaded references will be best solution
objectData
=
dict
(
objectData
)
objectData
=
dict
(
objectData
)
# now lets see if we have any references to the parent class here
# now lets see if we have any references to the parent class here
for
key
,
value
in
objectData
.
iteritems
(
):
for
key
,
value
in
six
.
iteritems
(
objectData
):
if
isinstance
(
value
,
dict
)
and
"className"
in
value
and
value
[
"className"
]
==
parent_class_name
:
if
isinstance
(
value
,
dict
)
and
"className"
in
value
and
value
[
"className"
]
==
parent_class_name
:
# simply put the reference here as a string -- not sure what the drawbacks are for this but it works for me
# simply put the reference here as a string -- not sure what the drawbacks are for this but it works for me
objectData
[
key
]
=
value
[
"objectId"
]
objectData
[
key
]
=
value
[
"objectId"
]
...
@@ -115,7 +117,6 @@ class Pointer(ParseType):
...
@@ -115,7 +117,6 @@ class Pointer(ParseType):
return
klass
(
**
objectData
)
return
klass
(
**
objectData
)
def
__init__
(
self
,
obj
):
def
__init__
(
self
,
obj
):
self
.
_object
=
obj
self
.
_object
=
obj
def
_to_native
(
self
):
def
_to_native
(
self
):
...
@@ -157,7 +158,7 @@ class Date(ParseType):
...
@@ -157,7 +158,7 @@ class Date(ParseType):
"""Can be initialized either with a string or a datetime"""
"""Can be initialized either with a string or a datetime"""
if
isinstance
(
date
,
datetime
.
datetime
):
if
isinstance
(
date
,
datetime
.
datetime
):
self
.
_date
=
date
self
.
_date
=
date
elif
isinstance
(
date
,
unicode
):
elif
isinstance
(
date
,
six
.
string_types
):
self
.
_date
=
Date
.
_from_str
(
date
)
self
.
_date
=
Date
.
_from_str
(
date
)
def
_to_native
(
self
):
def
_to_native
(
self
):
...
@@ -247,7 +248,6 @@ class ParseResource(ParseBase, Pointer):
...
@@ -247,7 +248,6 @@ class ParseResource(ParseBase, Pointer):
return
dict
([(
k
,
v
)
for
k
,
v
in
self
.
__dict__
.
items
()
if
allowed
(
k
)])
return
dict
([(
k
,
v
)
for
k
,
v
in
self
.
__dict__
.
items
()
if
allowed
(
k
)])
def
__init__
(
self
,
**
kw
):
def
__init__
(
self
,
**
kw
):
for
key
,
value
in
kw
.
items
():
for
key
,
value
in
kw
.
items
():
setattr
(
self
,
key
,
ParseType
.
convert_from_parse
(
value
,
self
.
__class__
.
__name__
))
setattr
(
self
,
key
,
ParseType
.
convert_from_parse
(
value
,
self
.
__class__
.
__name__
))
...
@@ -324,19 +324,21 @@ class ParseResource(ParseBase, Pointer):
...
@@ -324,19 +324,21 @@ class ParseResource(ParseBase, Pointer):
updatedAt
=
property
(
_get_updated_datetime
,
_set_updated_datetime
)
updatedAt
=
property
(
_get_updated_datetime
,
_set_updated_datetime
)
def
__repr__
(
self
):
def
__repr__
(
self
):
return
'<
%
s:
%
s>'
%
(
unicode
(
self
.
__class__
.
__name__
)
,
self
.
objectId
)
return
'<
%
s:
%
s>'
%
(
self
.
__class__
.
__name__
,
self
.
objectId
)
class
ObjectMetaclass
(
type
):
class
ObjectMetaclass
(
type
):
def
__new__
(
cls
,
name
,
bases
,
dct
):
def
__new__
(
mcs
,
name
,
bases
,
dct
):
cls
=
super
(
ObjectMetaclass
,
cls
)
.
__new__
(
cls
,
name
,
bases
,
dct
)
cls
=
super
(
ObjectMetaclass
,
mcs
)
.
__new__
(
mcs
,
name
,
bases
,
dct
)
# attr check must be here because of specific six.with_metaclass implemetantion where metaclass is used also for
# internal NewBase which hasn't set_endpoint_root method
if
hasattr
(
cls
,
'set_endpoint_root'
):
cls
.
set_endpoint_root
()
cls
.
set_endpoint_root
()
cls
.
Query
=
QueryManager
(
cls
)
cls
.
Query
=
QueryManager
(
cls
)
return
cls
return
cls
class
Object
(
ParseResource
):
class
Object
(
six
.
with_metaclass
(
ObjectMetaclass
,
ParseResource
)):
__metaclass__
=
ObjectMetaclass
ENDPOINT_ROOT
=
'/'
.
join
([
API_ROOT
,
'classes'
])
ENDPOINT_ROOT
=
'/'
.
join
([
API_ROOT
,
'classes'
])
@classmethod
@classmethod
...
@@ -357,7 +359,8 @@ class Object(ParseResource):
...
@@ -357,7 +359,8 @@ class Object(ParseResource):
@property
@property
def
_absolute_url
(
self
):
def
_absolute_url
(
self
):
if
not
self
.
objectId
:
return
None
if
not
self
.
objectId
:
return
None
return
'/'
.
join
([
self
.
__class__
.
ENDPOINT_ROOT
,
self
.
objectId
])
return
'/'
.
join
([
self
.
__class__
.
ENDPOINT_ROOT
,
self
.
objectId
])
@property
@property
...
...
parse_rest/installation.py
View file @
c6106771
...
@@ -11,9 +11,9 @@
...
@@ -11,9 +11,9 @@
# You should have received a copy of the GNU General Public License
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from
connection
import
API_ROOT
from
parse_rest.
connection
import
API_ROOT
from
datatypes
import
ParseResource
from
parse_rest.
datatypes
import
ParseResource
from
query
import
QueryManager
from
parse_rest.
query
import
QueryManager
class
Installation
(
ParseResource
):
class
Installation
(
ParseResource
):
...
...
parse_rest/query.py
View file @
c6106771
...
@@ -14,11 +14,8 @@
...
@@ -14,11 +14,8 @@
import
json
import
json
import
collections
import
collections
import
copy
import
copy
import
six
try
:
unicode
=
unicode
except
NameError
:
unicode
=
str
class
QueryResourceDoesNotExist
(
Exception
):
class
QueryResourceDoesNotExist
(
Exception
):
'''Query returned no results'''
'''Query returned no results'''
...
@@ -42,8 +39,7 @@ class QueryManager(object):
...
@@ -42,8 +39,7 @@ class QueryManager(object):
def
_count
(
self
,
**
kw
):
def
_count
(
self
,
**
kw
):
kw
.
update
({
"count"
:
1
,
"limit"
:
0
})
kw
.
update
({
"count"
:
1
,
"limit"
:
0
})
return
self
.
model_class
.
GET
(
self
.
model_class
.
ENDPOINT_ROOT
,
return
self
.
model_class
.
GET
(
self
.
model_class
.
ENDPOINT_ROOT
,
**
kw
)
.
get
(
'count'
)
**
kw
)
.
get
(
'count'
)
def
all
(
self
):
def
all
(
self
):
return
Queryset
(
self
)
return
Queryset
(
self
)
...
@@ -60,8 +56,8 @@ class QueryManager(object):
...
@@ -60,8 +56,8 @@ class QueryManager(object):
class
QuerysetMetaclass
(
type
):
class
QuerysetMetaclass
(
type
):
"""metaclass to add the dynamically generated comparison functions"""
"""metaclass to add the dynamically generated comparison functions"""
def
__new__
(
cl
s
,
name
,
bases
,
dct
):
def
__new__
(
mc
s
,
name
,
bases
,
dct
):
cls
=
super
(
QuerysetMetaclass
,
cls
)
.
__new__
(
cl
s
,
name
,
bases
,
dct
)
cls
=
super
(
QuerysetMetaclass
,
mcs
)
.
__new__
(
mc
s
,
name
,
bases
,
dct
)
for
fname
in
[
'limit'
,
'skip'
]:
for
fname
in
[
'limit'
,
'skip'
]:
def
func
(
self
,
value
,
fname
=
fname
):
def
func
(
self
,
value
,
fname
=
fname
):
...
@@ -73,8 +69,7 @@ class QuerysetMetaclass(type):
...
@@ -73,8 +69,7 @@ class QuerysetMetaclass(type):
return
cls
return
cls
class
Queryset
(
object
):
class
Queryset
(
six
.
with_metaclass
(
QuerysetMetaclass
,
object
)):
__metaclass__
=
QuerysetMetaclass
OPERATORS
=
[
OPERATORS
=
[
'lt'
,
'lte'
,
'gt'
,
'gte'
,
'ne'
,
'in'
,
'nin'
,
'exists'
,
'select'
,
'dontSelect'
,
'all'
,
'relatedTo'
'lt'
,
'lte'
,
'gt'
,
'gte'
,
'ne'
,
'in'
,
'nin'
,
'exists'
,
'select'
,
'dontSelect'
,
'all'
,
'relatedTo'
...
@@ -82,7 +77,7 @@ class Queryset(object):
...
@@ -82,7 +77,7 @@ class Queryset(object):
@staticmethod
@staticmethod
def
convert_to_parse
(
value
):
def
convert_to_parse
(
value
):
from
datatypes
import
ParseType
from
parse_rest.
datatypes
import
ParseType
return
ParseType
.
convert_to_parse
(
value
,
as_pointer
=
True
)
return
ParseType
.
convert_to_parse
(
value
,
as_pointer
=
True
)
@classmethod
@classmethod
...
@@ -143,8 +138,7 @@ class Queryset(object):
...
@@ -143,8 +138,7 @@ class Queryset(object):
self
.
_where
[
attr
][
'$'
+
operator
]
=
parse_value
self
.
_where
[
attr
][
'$'
+
operator
]
=
parse_value
except
TypeError
:
except
TypeError
:
# self._where[attr] wasn't settable
# self._where[attr] wasn't settable
raise
ValueError
(
"Cannot filter for a constraint "
+
raise
ValueError
(
"Cannot filter for a constraint after filtering for a specific value"
)
"after filtering for a specific value"
)
return
self
return
self
def
order_by
(
self
,
order
,
descending
=
False
):
def
order_by
(
self
,
order
,
descending
=
False
):
...
@@ -171,4 +165,4 @@ class Queryset(object):
...
@@ -171,4 +165,4 @@ class Queryset(object):
return
results
[
0
]
return
results
[
0
]
def
__repr__
(
self
):
def
__repr__
(
self
):
return
unicode
(
self
.
_fetch
())
return
repr
(
self
.
_fetch
())
parse_rest/tests.py
View file @
c6106771
This diff is collapsed.
Click to expand it.
parse_rest/user.py
View file @
c6106771
...
@@ -12,10 +12,10 @@
...
@@ -12,10 +12,10 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from
core
import
ResourceRequestLoginRequired
from
parse_rest.
core
import
ResourceRequestLoginRequired
from
connection
import
API_ROOT
from
parse_rest.
connection
import
API_ROOT
from
datatypes
import
ParseResource
,
ParseType
from
parse_rest.
datatypes
import
ParseResource
,
ParseType
from
query
import
QueryManager
from
parse_rest.
query
import
QueryManager
def
login_required
(
func
):
def
login_required
(
func
):
...
...
setup.py
View file @
c6106771
...
@@ -27,6 +27,7 @@ setup(
...
@@ -27,6 +27,7 @@ setup(
url
=
'https://github.com/dgrtwo/ParsePy'
,
url
=
'https://github.com/dgrtwo/ParsePy'
,
packages
=
[
'parse_rest'
],
packages
=
[
'parse_rest'
],
package_data
=
{
"parse_rest"
:
[
os
.
path
.
join
(
"cloudcode"
,
"*"
,
"*"
)]},
package_data
=
{
"parse_rest"
:
[
os
.
path
.
join
(
"cloudcode"
,
"*"
,
"*"
)]},
install_requires
=
[
'six'
],
maintainer
=
'David Robinson'
,
maintainer
=
'David Robinson'
,
maintainer_email
=
'dgrtwo@princeton.edu'
,
maintainer_email
=
'dgrtwo@princeton.edu'
,
cmdclass
=
{
'test'
:
TestCommand
},
cmdclass
=
{
'test'
:
TestCommand
},
...
@@ -36,6 +37,9 @@ setup(
...
@@ -36,6 +37,9 @@ setup(
'Intended Audience :: Developers'
,
'Intended Audience :: Developers'
,
'License :: OSI Approved :: GNU General Public License v3 (GPLv3)'
,
'License :: OSI Approved :: GNU General Public License v3 (GPLv3)'
,
'Operating System :: OS Independent'
,
'Operating System :: OS Independent'
,
'Programming Language :: Python'
"Programming Language :: Python :: 2.6"
,
"Programming Language :: Python :: 2.7"
,
"Programming Language :: Python :: 3.3"
,
"Programming Language :: Python :: 3.4"
,
]
]
)
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment