Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/sugar_network/node/routes.py
diff options
context:
space:
mode:
Diffstat (limited to 'sugar_network/node/routes.py')
-rw-r--r--sugar_network/node/routes.py69
1 files changed, 58 insertions, 11 deletions
diff --git a/sugar_network/node/routes.py b/sugar_network/node/routes.py
index 80caba4..9b0e27f 100644
--- a/sugar_network/node/routes.py
+++ b/sugar_network/node/routes.py
@@ -19,13 +19,13 @@ import shutil
import gettext
import logging
import hashlib
+from cStringIO import StringIO
from contextlib import contextmanager
from ConfigParser import ConfigParser
from os.path import join, isdir, exists
from sugar_network import node, toolkit, model
from sugar_network.node import stats_node, stats_user
-from sugar_network.model.context import Context
# pylint: disable-msg=W0611
from sugar_network.toolkit.router import route, preroute, postroute, ACL
from sugar_network.toolkit.router import Unauthorized, Request, fallbackroute
@@ -418,7 +418,6 @@ def load_bundle(volume, request, bundle_path):
if 'initial' in impl:
initial = impl.pop('initial')
data = impl.setdefault('data', {})
- data['blob'] = bundle_path
contexts = volume['context']
context = impl.get('context')
context_meta = None
@@ -445,7 +444,8 @@ def load_bundle(volume, request, bundle_path):
context = impl['context'] = spec['context']
impl['version'] = spec['version']
impl['stability'] = spec['stability']
- impl['license'] = spec['license']
+ if spec['license'] is not EMPTY_LICENSE:
+ impl['license'] = spec['license']
data['spec'] = {'*-*': {
'commands': spec.commands,
'requires': spec.requires,
@@ -463,25 +463,37 @@ def load_bundle(volume, request, bundle_path):
enforce('version' in impl, 'Version is not specified')
enforce(context_type in contexts.get(context)['type'],
http.BadRequest, 'Inappropriate bundle type')
- if impl.get('license') in (None, EMPTY_LICENSE):
+ if 'license' not in impl:
existing, total = impls.find(
context=context, order_by='-version', not_layer='deleted')
enforce(total, 'License is not specified')
impl['license'] = next(existing)['license']
+ digest = hashlib.sha1()
+ with file(bundle_path, 'rb') as f:
+ while True:
+ chunk = f.read(toolkit.BUFFER_SIZE)
+ if not chunk:
+ break
+ digest.update(chunk)
+ data['digest'] = digest.hexdigest()
+
yield impl
existing, __ = impls.find(
context=context, version=impl['version'], not_layer='deleted')
+ if 'url' not in data:
+ data['blob'] = bundle_path
impl['guid'] = \
request.call(method='POST', path=['implementation'], content=impl)
for i in existing:
layer = i['layer'] + ['deleted']
impls.update(i.guid, {'layer': layer})
- patch = contexts.patch(context, context_meta)
- if patch and 'origin' in impls.get(impl['guid']).layer:
- request.call(method='PUT', path=['context', context], content=patch)
+ if 'origin' in impls.get(impl['guid']).layer:
+ diff = contexts.patch(context, context_meta)
+ if diff:
+ request.call(method='PUT', path=['context', context], content=diff)
def _load_context_metadata(bundle, spec):
@@ -491,8 +503,18 @@ def _load_context_metadata(bundle, spec):
result[prop] = spec[prop]
try:
- with bundle.extractfile(join(bundle.rootdir, spec['icon'])) as svg:
- result.update(Context.image_props(svg))
+ icon_file = bundle.extractfile(join(bundle.rootdir, spec['icon']))
+ icon = StringIO(icon_file.read())
+ icon_file.close()
+ result.update({
+ 'artifact_icon': {
+ 'blob': icon,
+ 'mime_type': 'image/svg+xml',
+ 'digest': hashlib.sha1(icon.getvalue()).hexdigest(),
+ },
+ 'preview': _svg_to_png(icon.getvalue(), 160, 120),
+ 'icon': _svg_to_png(icon.getvalue(), 55, 55),
+ })
except Exception:
exception(_logger, 'Failed to load icon')
@@ -518,10 +540,35 @@ def _load_context_metadata(bundle, spec):
i18n = gettext.translation(spec['context'],
join(tmpdir, *mo_path[:2]), [lang])
for prop, value in msgids.items():
- msgstr = i18n.gettext(value)
- if msgstr != value or lang == 'en':
+ msgstr = i18n.gettext(value).decode('utf8')
+ if lang == 'en' or msgstr != value:
result[prop][lang] = msgstr
except Exception:
exception(_logger, 'Gettext failed to read %r', mo_path[-1])
return result
+
+
+def _svg_to_png(data, w, h):
+ import rsvg
+ import cairo
+
+ svg = rsvg.Handle(data=data)
+ surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, w, h)
+ context = cairo.Context(surface)
+
+ scale = min(float(w) / svg.props.width, float(h) / svg.props.height)
+ context.translate(
+ int(w - svg.props.width * scale) / 2,
+ int(h - svg.props.height * scale) / 2)
+ context.scale(scale, scale)
+ svg.render_cairo(context)
+
+ result = StringIO()
+ surface.write_to_png(result)
+ result.seek(0)
+
+ return {'blob': result,
+ 'mime_type': 'image/png',
+ 'digest': hashlib.sha1(result.getvalue()).hexdigest(),
+ }