mirror of
https://github.com/ankitects/anki.git
synced 2025-11-07 13:17:12 -05:00
move common auth+upload code into base class
This commit is contained in:
parent
bf3bb9dd32
commit
a8d2578be5
1 changed files with 74 additions and 63 deletions
137
anki/sync.py
137
anki/sync.py
|
|
@ -389,10 +389,71 @@ class LocalServer(Syncer):
|
|||
l = simplejson.loads; d = simplejson.dumps
|
||||
return l(d(Syncer.applyChanges(self, minUsn, lnewer, l(d(changes)))))
|
||||
|
||||
# Syncing over HTTP
|
||||
# HTTP syncing tools
|
||||
##########################################################################
|
||||
|
||||
class RemoteServer(Syncer):
|
||||
class HttpSyncer(object):
|
||||
|
||||
# retrieving a host key for future operations
|
||||
def hostKey(self, pw):
|
||||
h = httplib2.Http(timeout=60)
|
||||
resp, cont = h.request(
|
||||
SYNC_URL+"hostKey?" + urllib.urlencode(dict(u=self.user,p=pw)))
|
||||
if resp['status'] != '200':
|
||||
raise Exception("Invalid response code: %s" % resp['status'])
|
||||
self.hkey = cont
|
||||
return cont
|
||||
|
||||
# Posting data as a file
|
||||
######################################################################
|
||||
# We don't want to post the payload as a form var, as the percent-encoding is
|
||||
# costly. We could send it as a raw post, but more HTTP clients seem to
|
||||
# support file uploading, so this is the more compatible choice.
|
||||
|
||||
def postData(self, http, method, fobj, vars, comp=1):
|
||||
bdry = "--"+MIME_BOUNDARY
|
||||
# write out post vars, including session key and compression flag
|
||||
buf = StringIO()
|
||||
vars = vars or {}
|
||||
vars['c'] = 1 if comp else 0
|
||||
for (key, value) in vars.items():
|
||||
buf.write(bdry + "\r\n")
|
||||
buf.write(
|
||||
'Content-Disposition: form-data; name="%s"\r\n\r\n%s\r\n' %
|
||||
(key, value))
|
||||
# file header
|
||||
buf.write(bdry + "\r\n")
|
||||
buf.write("""\
|
||||
Content-Disposition: form-data; name="data"; filename="data"\r\n\
|
||||
Content-Type: application/octet-stream\r\n\r\n""")
|
||||
# write file into buffer, optionally compressing
|
||||
if comp:
|
||||
tgt = gzip.GzipFile(mode="wb", fileobj=buf, compresslevel=comp)
|
||||
else:
|
||||
tgt = buf
|
||||
while 1:
|
||||
data = fobj.read(CHUNK_SIZE)
|
||||
if not data:
|
||||
if comp:
|
||||
tgt.close()
|
||||
break
|
||||
tgt.write(data)
|
||||
buf.write('\r\n' + bdry + '--\r\n')
|
||||
size = buf.tell()
|
||||
# connection headers
|
||||
headers = {
|
||||
'Content-Type': 'multipart/form-data; boundary=%s' % MIME_BOUNDARY,
|
||||
'Content-Length': str(size),
|
||||
}
|
||||
body = buf.getvalue()
|
||||
buf.close()
|
||||
resp, cont = http.request(
|
||||
SYNC_URL+method, "POST", headers=headers, body=body)
|
||||
if resp['status'] != '200':
|
||||
raise Exception("Invalid response code: %s" % resp['status'])
|
||||
return cont
|
||||
|
||||
class RemoteServer(Syncer, HttpSyncer):
|
||||
def __init__(self, user, hkey):
|
||||
self.user = user
|
||||
self.hkey = hkey
|
||||
|
|
@ -413,15 +474,6 @@ class RemoteServer(Syncer):
|
|||
raise Exception("Invalid response code: %s" % resp['status'])
|
||||
return simplejson.loads(cont)
|
||||
|
||||
def hostKey(self, pw):
|
||||
h = httplib2.Http(timeout=60)
|
||||
resp, cont = h.request(
|
||||
SYNC_URL+"hostKey?" + urllib.urlencode(dict(u=self.user,p=pw)))
|
||||
if resp['status'] != '200':
|
||||
raise Exception("Invalid response code: %s" % resp['status'])
|
||||
self.hkey = cont
|
||||
return cont
|
||||
|
||||
def applyChanges(self, **kw):
|
||||
self.con = httplib2.Http(timeout=60)
|
||||
return self._run("applyChanges", kw)
|
||||
|
|
@ -443,13 +495,13 @@ class RemoteServer(Syncer):
|
|||
|
||||
def _run(self, cmd, data):
|
||||
return simplejson.loads(
|
||||
postData(self.con, cmd, StringIO(simplejson.dumps(data)),
|
||||
self._vars()))
|
||||
self.postData(self.con, cmd, StringIO(simplejson.dumps(data)),
|
||||
self._vars()))
|
||||
|
||||
# Full syncing
|
||||
##########################################################################
|
||||
|
||||
class FullSyncer(object):
|
||||
class FullSyncer(HttpSyncer):
|
||||
|
||||
def __init__(self, deck, hkey):
|
||||
self.deck = deck
|
||||
|
|
@ -477,54 +529,13 @@ class FullSyncer(object):
|
|||
|
||||
def upload(self):
|
||||
self.deck.beforeUpload()
|
||||
assert postData(self._con(), "upload", open(self.deck.path, "rb"),
|
||||
self._vars(), comp=6) == "OK"
|
||||
assert self.postData(self._con(), "upload", open(self.deck.path, "rb"),
|
||||
self._vars(), comp=6) == "OK"
|
||||
|
||||
# Media syncing
|
||||
##########################################################################
|
||||
|
||||
class MediaSyncer(HttpSyncer):
|
||||
pass
|
||||
|
||||
# Posting data as a file
|
||||
######################################################################
|
||||
# We don't want to post the payload as a form var, as the percent-encoding is
|
||||
# costly. We could send it as a raw post, but more HTTP clients seem to
|
||||
# support file uploading, so this is the more compatible choice.
|
||||
|
||||
def postData(http, method, fobj, vars, comp=1):
|
||||
bdry = "--"+MIME_BOUNDARY
|
||||
# write out post vars, including session key and compression flag
|
||||
buf = StringIO()
|
||||
vars = vars or {}
|
||||
vars['c'] = 1 if comp else 0
|
||||
for (key, value) in vars.items():
|
||||
buf.write(bdry + "\r\n")
|
||||
buf.write(
|
||||
'Content-Disposition: form-data; name="%s"\r\n\r\n%s\r\n' %
|
||||
(key, value))
|
||||
# file header
|
||||
buf.write(bdry + "\r\n")
|
||||
buf.write("""\
|
||||
Content-Disposition: form-data; name="data"; filename="data"\r\n\
|
||||
Content-Type: application/octet-stream\r\n\r\n""")
|
||||
# write file into buffer, optionally compressing
|
||||
if comp:
|
||||
tgt = gzip.GzipFile(mode="wb", fileobj=buf, compresslevel=comp)
|
||||
else:
|
||||
tgt = buf
|
||||
while 1:
|
||||
data = fobj.read(CHUNK_SIZE)
|
||||
if not data:
|
||||
if comp:
|
||||
tgt.close()
|
||||
break
|
||||
tgt.write(data)
|
||||
buf.write('\r\n' + bdry + '--\r\n')
|
||||
size = buf.tell()
|
||||
# connection headers
|
||||
headers = {
|
||||
'Content-Type': 'multipart/form-data; boundary=%s' % MIME_BOUNDARY,
|
||||
'Content-Length': str(size),
|
||||
}
|
||||
body = buf.getvalue()
|
||||
buf.close()
|
||||
resp, cont = http.request(
|
||||
SYNC_URL+method, "POST", headers=headers, body=body)
|
||||
if resp['status'] != '200':
|
||||
raise Exception("Invalid response code: %s" % resp['status'])
|
||||
return cont
|
||||
|
|
|
|||
Loading…
Reference in a new issue