Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAleksey Lim <alsroot@sugarlabs.org>2014-04-29 01:46:33 (GMT)
committer Aleksey Lim <alsroot@sugarlabs.org>2014-04-29 01:46:33 (GMT)
commit686643208fd9363487f0c89c53440db9d7fd42b3 (patch)
treee1a48ea6319356931092a673d0f8f0ac5def70a1
parent0438dbe5fba595a11a77c5a311512e48cb9cad33 (diff)
Fix file-less blobs behaviour
-rw-r--r--sugar_network/db/blobs.py29
-rw-r--r--sugar_network/db/routes.py6
-rw-r--r--sugar_network/node/model.py44
-rwxr-xr-xtests/units/client/client_routes.py4
-rwxr-xr-xtests/units/db/blobs.py41
5 files changed, 71 insertions, 53 deletions
diff --git a/sugar_network/db/blobs.py b/sugar_network/db/blobs.py
index 95f1a4e..cc0944f 100644
--- a/sugar_network/db/blobs.py
+++ b/sugar_network/db/blobs.py
@@ -119,10 +119,12 @@ class Blobs(object):
elif isinstance(content, dict):
enforce('location' in content, http.BadRequest, 'No location')
enforce('digest' in content, http.BadRequest, 'No digest')
+ enforce('content-length' in content, http.BadRequest,
+ 'No content-length')
meta.append(('status', '301 Moved Permanently'))
meta.append(('location', content['location']))
- with toolkit.new_file(tmp_path) as blob:
- yield blob, content['digest']
+ meta.append(('content-length', content['content-length']))
+ yield None, content['digest']
else:
with toolkit.new_file(tmp_path) as blob:
blob.write(content)
@@ -130,13 +132,15 @@ class Blobs(object):
with write_blob() as (blob, digest):
if digest_to_assert and digest != digest_to_assert:
- blob.unlink()
+ if blob is not None:
+ blob.unlink()
raise http.BadRequest('Digest mismatch')
path = self._blob_path(digest)
seqno = self._seqno.next()
- meta.append(('content-length', str(blob.tell())))
meta.append(('x-seqno', str(seqno)))
- blob.name = path
+ if blob is not None:
+ meta.append(('content-length', str(blob.tell())))
+ blob.name = path
_write_meta(path, meta, seqno)
_logger.debug('Post %r file', path)
@@ -157,7 +161,10 @@ class Blobs(object):
elif isdir(path):
return _lsdir(path, digest)
elif exists(path):
- return File(path, digest)
+ blob = File(path, digest)
+ blob.meta.set('content-length', str(blob.size))
+ blob.meta.set('content-type', _guess_mime(path))
+ return blob
def delete(self, path):
self._delete(self.path(path), None)
@@ -206,12 +213,10 @@ class Blobs(object):
continue
else:
_logger.debug('Found new %r blob', path)
- mime_type = mimetypes.guess_type(filename)[0] or \
- 'application/octet-stream'
if checkin_seqno is None:
checkin_seqno = self._seqno.next()
seqno = checkin_seqno
- meta = [('content-type', mime_type),
+ meta = [('content-type', _guess_mime(filename)),
('content-length', str(os.stat(path).st_size)),
('x-seqno', str(seqno)),
]
@@ -263,7 +268,7 @@ class Blobs(object):
def _write_meta(path, meta, seqno):
- if seqno:
+ if seqno and exists(path):
os.utime(path, (seqno, seqno))
path += _META_SUFFIX
with toolkit.new_file(path) as f:
@@ -288,3 +293,7 @@ def _lsdir(root, rel_root):
path = join(root, filename)
if exists(path + _META_SUFFIX):
yield File(path, join(rel_root, filename), _read_meta(path))
+
+
+def _guess_mime(path):
+ return mimetypes.guess_type(path)[0] or 'application/octet-stream'
diff --git a/sugar_network/db/routes.py b/sugar_network/db/routes.py
index 0ea1305..4c29780 100644
--- a/sugar_network/db/routes.py
+++ b/sugar_network/db/routes.py
@@ -81,7 +81,9 @@ class Routes(object):
def find(self, reply, limit):
self._preget()
request = this.request
- if self._find_limit and limit > self._find_limit:
+ if not limit:
+ request['limit'] = self._find_limit
+ elif self._find_limit and limit > self._find_limit:
_logger.warning('The find limit is restricted to %s',
self._find_limit)
request['limit'] = self._find_limit
@@ -168,7 +170,7 @@ class Routes(object):
@fallbackroute('GET', ['blobs'])
def blobs(self):
- return self.volume.blobs.get(this.request.guid)
+ return self.volume.blobs.get(this.request.path[1:])
@contextmanager
def _post(self, access):
diff --git a/sugar_network/node/model.py b/sugar_network/node/model.py
index f178913..d2a6475 100644
--- a/sugar_network/node/model.py
+++ b/sugar_network/node/model.py
@@ -422,10 +422,10 @@ def presolve(presolve_path):
obs.presolve(repo_name, pkgs, presolve_path)
-def load_bundle(blob, context=None, initial=False, extra_deps=None):
+def load_bundle(blob, context=None, initial=False, extra_deps=None,
+ license=None, release_notes=None):
context_type = None
context_meta = None
- release_notes = None
version = None
release = _ReleaseValue()
release.guid = blob.digest
@@ -437,16 +437,12 @@ def load_bundle(blob, context=None, initial=False, extra_deps=None):
if not context:
context = this.request['context']
version = this.request['version']
- if 'license' in this.request:
- release['license'] = this.request['license']
- if isinstance(release['license'], basestring):
- release['license'] = [release['license']]
- release['stability'] = 'stable'
release['bundles'] = {
'*-*': {
'blob': blob.digest,
},
}
+ release['stability'] = 'stable'
else:
context_type = 'activity'
unpack_size = 0
@@ -454,7 +450,7 @@ def load_bundle(blob, context=None, initial=False, extra_deps=None):
with bundle:
changelog = join(bundle.rootdir, 'CHANGELOG')
for arcname in bundle.get_names():
- if changelog and arcname == changelog:
+ if not release_notes and changelog and arcname == changelog:
with bundle.extractfile(changelog) as f:
release_notes = f.read()
changelog = None
@@ -472,8 +468,6 @@ def load_bundle(blob, context=None, initial=False, extra_deps=None):
version = spec['version']
release['stability'] = spec['stability']
- if spec['license'] is not EMPTY_LICENSE:
- release['license'] = spec['license']
release['commands'] = spec.commands
release['requires'] = spec.requires
release['bundles'] = {
@@ -482,6 +476,8 @@ def load_bundle(blob, context=None, initial=False, extra_deps=None):
'unpack_size': unpack_size,
},
}
+ if not license and spec['license'] is not EMPTY_LICENSE:
+ license = spec['license']
blob.meta['content-type'] = 'application/vnd.olpc-sugar'
enforce(context, http.BadRequest, 'Context is not specified')
@@ -502,12 +498,18 @@ def load_bundle(blob, context=None, initial=False, extra_deps=None):
enforce(context_type in doc['type'],
http.BadRequest, 'Inappropriate bundle type')
- if 'license' not in release:
+ if not license:
+ license = this.request.get('license')
+ if license:
+ if isinstance(license, basestring):
+ license = [license]
+ else:
releases = doc['releases'].values()
enforce(releases, http.BadRequest, 'License is not specified')
recent = max(releases, key=lambda x: x.get('value', {}).get('release'))
enforce(recent, http.BadRequest, 'License is not specified')
- release['license'] = recent['value']['license']
+ license = recent['value']['license']
+ release['license'] = license
_logger.debug('Load %r release: %r', context, release)
@@ -522,17 +524,15 @@ def load_bundle(blob, context=None, initial=False, extra_deps=None):
else:
# TRANS: 3rd party release notes title
title = i18n._('%(name)s %(version)s third-party release')
+ announce = {
+ 'context': context,
+ 'type': 'notification',
+ 'title': i18n.encode(title, name=doc['title'], version=version),
+ 'message': release_notes or '',
+ }
release['announce'] = this.call(method='POST', path=['post'],
- content={
- 'context': context,
- 'type': 'notification',
- 'title': i18n.encode(title,
- name=doc['title'],
- version=version,
- ),
- 'message': release_notes or '',
- },
- content_type='application/json', principal=this.principal)
+ content=announce, content_type='application/json',
+ principal=this.principal)
blob.meta['content-disposition'] = 'attachment; filename="%s-%s%s"' % (
''.join(i18n.decode(doc['title']).split()), version,
diff --git a/tests/units/client/client_routes.py b/tests/units/client/client_routes.py
index c000442..bc7572f 100755
--- a/tests/units/client/client_routes.py
+++ b/tests/units/client/client_routes.py
@@ -981,9 +981,11 @@ class ClientRoutesTest(tests.Test):
coroutine.sleep(1)
yield 'emote"'
+ trigger = self.wait_for_events(ipc, event='inline', state='online')
+ coroutine.dispatch()
node_pid = self.fork_master([User], NodeRoutes)
self.client_routes._remote_connect()
- self.wait_for_events(ipc, event='inline', state='online').wait()
+ trigger.wait()
ts = time.time()
self.assertEqual('remote', ipc.get(cmd='sleep'))
diff --git a/tests/units/db/blobs.py b/tests/units/db/blobs.py
index 35ebb62..d5d2b1e 100755
--- a/tests/units/db/blobs.py
+++ b/tests/units/db/blobs.py
@@ -40,12 +40,13 @@ class BlobsTest(tests.Test):
self.assertEqual(
content,
file(blob.path).read())
- self.assertEqual([
- 'content-type: application/octet-stream',
- 'content-length: %s' % len(content),
- 'x-seqno: 1',
- ],
- file(blob.path + '.meta').read().strip().split('\n'))
+ self.assertEqual(
+ sorted([
+ 'content-type: application/octet-stream',
+ 'content-length: %s' % len(content),
+ 'x-seqno: 1',
+ ]),
+ sorted(file(blob.path + '.meta').read().strip().split('\n')))
the_same_blob = blobs.get(blob.digest)
assert the_same_blob is not blob
@@ -75,12 +76,13 @@ class BlobsTest(tests.Test):
self.assertEqual(
content,
file(blob.path).read())
- self.assertEqual([
- 'content-type: application/octet-stream',
- 'content-length: %s' % len(content),
- 'x-seqno: 1',
- ],
- file(blob.path + '.meta').read().strip().split('\n'))
+ self.assertEqual(
+ sorted([
+ 'content-type: application/octet-stream',
+ 'content-length: %s' % len(content),
+ 'x-seqno: 1',
+ ]),
+ sorted(file(blob.path + '.meta').read().strip().split('\n')))
the_same_blob = blobs.get(blob.digest)
assert the_same_blob is not blob
@@ -93,7 +95,12 @@ class BlobsTest(tests.Test):
self.assertRaises(http.BadRequest, blobs.post, {})
self.assertRaises(http.BadRequest, blobs.post, {'digest': 'digest'})
- blob = blobs.post({'location': 'location', 'digest': '0000000000000000000000000000000000000000', 'foo': 'bar'})
+ blob = blobs.post({
+ 'location': 'location',
+ 'digest': '0000000000000000000000000000000000000000',
+ 'content-length': '101',
+ 'foo': 'bar',
+ })
self.assertEqual(
'0000000000000000000000000000000000000000',
@@ -105,20 +112,18 @@ class BlobsTest(tests.Test):
'status': '301 Moved Permanently',
'location': 'location',
'content-type': 'application/octet-stream',
- 'content-length': '0',
+ 'content-length': '101',
'x-seqno': '1',
},
blob.meta)
- self.assertEqual(
- '',
- file(blob.path).read())
+ assert not exists(blob.path)
self.assertEqual(
sorted([
'status: 301 Moved Permanently',
'location: location',
'content-type: application/octet-stream',
- 'content-length: 0',
+ 'content-length: 101',
'x-seqno: 1',
]),
sorted(file(blob.path + '.meta').read().strip().split('\n')))