Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAleksey Lim <alsroot@sugarlabs.org>2012-09-09 15:12:33 (GMT)
committer Aleksey Lim <alsroot@sugarlabs.org>2012-09-09 15:12:33 (GMT)
commita05942e9473696c65760050a0a23acfd43ea8155 (patch)
tree3821ad9edaa19a55098f9b877813ee92d665b198
parent521eb6e45c8115eef0071864b2bbecec878a9166 (diff)
Provide default context icons
-rw-r--r--README8
-rw-r--r--sugar_network/node/router.py18
-rw-r--r--sugar_network/resources/context.py20
-rw-r--r--sugar_network/static/__init__.py19
-rw-r--r--sugar_network/static/images/missing.pngbin0 -> 2727 bytes
-rw-r--r--sugar_network/static/images/missing.svg69
-rw-r--r--sugar_network/static/images/package.pngbin0 -> 3834 bytes
-rw-r--r--tests/__init__.py1
-rwxr-xr-xtests/units/home_mount.py21
-rwxr-xr-xtests/units/node.py17
-rwxr-xr-xtests/units/node_mount.py24
-rwxr-xr-xtests/units/remote_mount.py18
-rwxr-xr-xtests/units/router.py7
13 files changed, 197 insertions, 25 deletions
diff --git a/README b/README
index e1c8b90..faa8de9 100644
--- a/README
+++ b/README
@@ -11,5 +11,13 @@ Clone source repository from `Gitorious`_ project:
``git clone git://git.sugarlabs.org/network/client.git``
+Artwork
+=======
+
+* `sugar-artwork`_ images.
+* `Oxygen`_ icons.
+
.. _home page: http://wiki.sugarlabs.org/go/Platform_Team/Sugar_Network/Client
.. _Gitorious: http://git.sugarlabs.org/network
+.. _sugar-artwork: http://git.sugarlabs.org/sugar-artwork
+.. _Oxygen: http://www.oxygen-icons.org/
diff --git a/sugar_network/node/router.py b/sugar_network/node/router.py
index 57ffa1d..888235c 100644
--- a/sugar_network/node/router.py
+++ b/sugar_network/node/router.py
@@ -17,13 +17,13 @@ import os
import cgi
import json
import types
-import urllib
import logging
from urlparse import parse_qsl
from bisect import bisect_left
+from os.path import join, isfile
import active_document as ad
-from sugar_network import node
+from sugar_network import node, static
from active_toolkit.sockets import BUFFER_SIZE
from active_toolkit import util, enforce
@@ -52,7 +52,12 @@ class Router(object):
try:
request.principal = self._authenticate(request)
- result = self._cp.call(request, response)
+ if request.path[:1] == ['static']:
+ static_path = join(static.PATH, *request.path[1:])
+ enforce(isfile(static_path), 'No such file')
+ result = file(static_path)
+ else:
+ result = self._cp.call(request, response)
except ad.Redirect, error:
response.status = '303 See Other'
response['Location'] = error.location
@@ -130,11 +135,8 @@ class _Request(ad.Request):
self.access_level = ad.ACCESS_REMOTE
self.environ = environ
- path = environ['PATH_INFO'] or '/'
- __, path = urllib.splittype(path)
- __, path = urllib.splithost(path)
- self.url = path
- self.path = [i for i in path.strip('/').split('/') if i]
+ self.url = '/' + environ['PATH_INFO'].strip('/')
+ self.path = [i for i in self.url[1:].split('/') if i]
self['method'] = environ['REQUEST_METHOD']
self.content = None
self.content_stream = environ.get('wsgi.input')
diff --git a/sugar_network/resources/context.py b/sugar_network/resources/context.py
index 8a6c66f..e670d10 100644
--- a/sugar_network/resources/context.py
+++ b/sugar_network/resources/context.py
@@ -13,9 +13,11 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
+from os.path import join
+
import active_document as ad
-from sugar_network import resources
+from sugar_network import resources, static
from sugar_network.resources.volume import Resource
@@ -58,10 +60,24 @@ class Context(Resource):
@ad.active_property(ad.BlobProperty, mime_type='image/png')
def icon(self, value):
- return value
+ if value is None:
+ if 'package' in self['type']:
+ return {'url': '/static/images/package.png',
+ 'path': join(static.PATH, 'images', 'package.png'),
+ 'mime_type': 'image/png'}
+ else:
+ return {'url': '/static/images/missing.png',
+ 'path': join(static.PATH, 'images', 'missing.png'),
+ 'mime_type': 'image/png'}
+ else:
+ return value
@ad.active_property(ad.BlobProperty, mime_type='image/svg+xml')
def artifact_icon(self, value):
+ if value is None:
+ return {'url': '/static/images/missing.svg',
+ 'path': join(static.PATH, 'images', 'missing.svg'),
+ 'mime_type': 'image/svg+xml'}
return value
@ad.active_property(ad.BlobProperty)
diff --git a/sugar_network/static/__init__.py b/sugar_network/static/__init__.py
new file mode 100644
index 0000000..e65e61d
--- /dev/null
+++ b/sugar_network/static/__init__.py
@@ -0,0 +1,19 @@
+# Copyright (C) 2012 Aleksey Lim
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+from os.path import dirname
+
+
+PATH = dirname(__file__)
diff --git a/sugar_network/static/images/missing.png b/sugar_network/static/images/missing.png
new file mode 100644
index 0000000..8d6c26d
--- /dev/null
+++ b/sugar_network/static/images/missing.png
Binary files differ
diff --git a/sugar_network/static/images/missing.svg b/sugar_network/static/images/missing.svg
new file mode 100644
index 0000000..cba7e35
--- /dev/null
+++ b/sugar_network/static/images/missing.svg
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.0"
+ width="75"
+ height="75"
+ viewBox="-13.5 -13.5 75 75"
+ id="svg1872"
+ sodipodi:version="0.32"
+ inkscape:version="0.44"
+ sodipodi:docname="stock-missing.svg"
+ sodipodi:docbase="/home/marco/sugar-jhbuild/source/artwork/art/icon-theme/scalable/stock">
+ <metadata
+ id="metadata42">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <sodipodi:namedview
+ inkscape:window-height="624"
+ inkscape:window-width="860"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ guidetolerance="10.0"
+ gridtolerance="10.0"
+ objecttolerance="10.0"
+ borderopacity="1.0"
+ bordercolor="#666666"
+ pagecolor="#ffffff"
+ id="base"
+ inkscape:zoom="8.4791667"
+ inkscape:cx="24"
+ inkscape:cy="24.058968"
+ inkscape:window-x="55"
+ inkscape:window-y="49"
+ inkscape:current-layer="svg1872" />
+ <defs
+ id="defs1874" />
+ <g
+ id="layer1">
+ <path
+ d="M 46.857141 26.285715 A 25.142857 16.714285 0 1 1 -3.4285717,26.285715 A 25.142857 16.714285 0 1 1 46.857141 26.285715 z"
+ transform="matrix(0.889463,0,0,1.337995,4.685959,-11.17014)"
+ style="opacity:0.66976743;fill:#8a8c90;fill-opacity:1;stroke:black;stroke-width:3;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="path4550" />
+ <text
+ x="4.7315407"
+ y="46.846149"
+ transform="scale(1.186648,0.84271)"
+ style="font-size:50.32819366px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ id="text4552"
+ xml:space="preserve"><tspan
+ x="4.7315407"
+ y="46.846149"
+ id="tspan4554" /></text>
+ </g>
+</svg>
diff --git a/sugar_network/static/images/package.png b/sugar_network/static/images/package.png
new file mode 100644
index 0000000..b8134cf
--- /dev/null
+++ b/sugar_network/static/images/package.png
Binary files differ
diff --git a/tests/__init__.py b/tests/__init__.py
index a1a83af..2c455c0 100644
--- a/tests/__init__.py
+++ b/tests/__init__.py
@@ -93,6 +93,7 @@ class Test(unittest.TestCase):
Volume.RESOURCES = [
'sugar_network.resources.user',
'sugar_network.resources.context',
+ 'sugar_network.resources.report',
]
sugar.nickname = lambda: 'test'
diff --git a/tests/units/home_mount.py b/tests/units/home_mount.py
index a470200..c9c9119 100755
--- a/tests/units/home_mount.py
+++ b/tests/units/home_mount.py
@@ -9,6 +9,7 @@ from __init__ import tests
from active_toolkit import sockets, coroutine
from sugar_network import Client
+from sugar_network.resources.report import Report
class HomeMountTest(tests.Test):
@@ -119,6 +120,19 @@ class HomeMountTest(tests.Test):
assert not exists('file2')
def test_GetAbsetnBLOB(self):
+ self.start_server([Report])
+ client = Client('~')
+
+ guid = client.Report(
+ context='context',
+ implementation='implementation',
+ description='description').post()
+
+ path, mime_type = client.Report(guid).get_blob_path('data')
+ self.assertEqual(None, path)
+ self.assertEqual(True, client.Report(guid).get_blob('data').closed)
+
+ def test_GetDefaultBLOB(self):
self.start_server()
client = Client('~')
@@ -129,8 +143,9 @@ class HomeMountTest(tests.Test):
description='description').post()
path, mime_type = client.Context(guid).get_blob_path('icon')
- self.assertEqual(None, path)
- self.assertEqual(True, client.Context(guid).get_blob('icon').closed)
+ assert path.endswith('missing.png')
+ assert exists(path)
+ self.assertEqual(False, client.Context(guid).get_blob('icon').closed)
def test_Subscription(self):
self.start_server()
@@ -202,7 +217,7 @@ class HomeMountTest(tests.Test):
event = subscription.read_message()
event.pop('props')
self.assertEqual(
- {'document': 'context', 'event': 'update', 'guid': guid, 'seqno': 2},
+ {'document': 'context', 'event': 'update', 'guid': guid, 'seqno': 4},
event)
def test_Connect(self):
diff --git a/tests/units/node.py b/tests/units/node.py
index ea3c120..4d54456 100755
--- a/tests/units/node.py
+++ b/tests/units/node.py
@@ -282,9 +282,14 @@ class NodeTest(tests.Test):
'description': 'description',
})
volume['context'].set_blob(guid3, 'icon', '/foo/bar')
+ guid4 = call(cp, method='POST', document='report', principal='principal', content={
+ 'context': 'context',
+ 'implementation': 'implementation',
+ 'description': 'description',
+ })
self.assertEqual(
- {'guid': guid1, 'icon': 'http://localhost:8000/context/%s/icon' % guid1},
+ {'guid': guid1, 'icon': 'http://localhost:8000/static/images/missing.png'},
call(cp, method='GET', document='context', guid=guid1, reply=['guid', 'icon']))
self.assertEqual(
{'guid': guid2, 'icon': 'http://foo/bar'},
@@ -292,14 +297,22 @@ class NodeTest(tests.Test):
self.assertEqual(
{'guid': guid3, 'icon': 'http://localhost:8000/foo/bar'},
call(cp, method='GET', document='context', guid=guid3, reply=['guid', 'icon']))
+ self.assertEqual(
+ {'guid': guid4, 'data': 'http://localhost:8000/report/%s/data' % guid4},
+ call(cp, method='GET', document='report', guid=guid4, reply=['guid', 'data']))
self.assertEqual([
- {'guid': guid1, 'icon': 'http://localhost:8000/context/%s/icon' % guid1},
+ {'guid': guid1, 'icon': 'http://localhost:8000/static/images/missing.png'},
{'guid': guid2, 'icon': 'http://foo/bar'},
{'guid': guid3, 'icon': 'http://localhost:8000/foo/bar'},
],
call(cp, method='GET', document='context', reply=['guid', 'icon'])['result'])
+ self.assertEqual([
+ {'guid': guid4, 'data': 'http://localhost:8000/report/%s/data' % guid4},
+ ],
+ call(cp, method='GET', document='report', reply=['guid', 'data'])['result'])
+
def call(cp, principal=None, content=None, **kwargs):
request = ad.Request(**kwargs)
diff --git a/tests/units/node_mount.py b/tests/units/node_mount.py
index 8aa0043..eed94f7 100755
--- a/tests/units/node_mount.py
+++ b/tests/units/node_mount.py
@@ -20,6 +20,7 @@ from sugar_network.resources.user import User
from sugar_network.resources.context import Context
from sugar_network import local, Client, sugar
from sugar_network.resources.volume import Volume
+from sugar_network.resources.report import Report
class NodeMountTest(tests.Test):
@@ -34,7 +35,7 @@ class NodeMountTest(tests.Test):
def start_server(self, ipc=False):
local.mounts_root.value = tests.tmpdir
- volume = Volume('local', [User, Context])
+ volume = Volume('local', [User, Context, Report])
mounts = Mountset(volume)
if ipc:
self.server = IPCServer(mounts)
@@ -325,6 +326,22 @@ class NodeMountTest(tests.Test):
self.got_event.wait()
client = Client(tests.tmpdir + '/mnt')
+ guid = client.Report(
+ context='context',
+ implementation='implementation',
+ description='description').post()
+
+ path, mime_type = client.Report(guid).get_blob_path('data')
+ self.assertEqual(None, path)
+ self.assertEqual(True, client.Report(guid).get_blob('data').closed)
+
+ def test_GetDefaultBLOB(self):
+ self.touch('mnt/.sugar-network')
+ self.touch(('mnt/node', 'node'))
+ self.start_server()
+ self.got_event.wait()
+ client = Client(tests.tmpdir + '/mnt')
+
guid = client.Context(
type='activity',
title='title',
@@ -332,8 +349,9 @@ class NodeMountTest(tests.Test):
description='description').post()
path, mime_type = client.Context(guid).get_blob_path('icon')
- self.assertEqual(None, path)
- self.assertEqual(True, client.Context(guid).get_blob('icon').closed)
+ assert path.endswith('missing.png')
+ assert exists(path)
+ self.assertEqual(False, client.Context(guid).get_blob('icon').closed)
def test_get_blob_ExtractImplementations(self):
Volume.RESOURCES = [
diff --git a/tests/units/remote_mount.py b/tests/units/remote_mount.py
index 45876dd..b06e686 100755
--- a/tests/units/remote_mount.py
+++ b/tests/units/remote_mount.py
@@ -17,6 +17,7 @@ from sugar_network.local.bus import IPCServer
from sugar_network.toolkit import sugar, http
from sugar_network.resources.user import User
from sugar_network.resources.context import Context
+from sugar_network.resources.report import Report
from sugar_network.resources.volume import Volume
@@ -297,6 +298,19 @@ class RemoteMountTest(tests.Test):
self.assertEqual(4, json.load(file(cache_path + '.meta'))['seqno'])
def test_GetAbsentBLOB(self):
+ self.start_ipc_and_restful_server([User, Report])
+ client = Client('/')
+
+ guid = client.Report(
+ context='context',
+ implementation='implementation',
+ description='description').post()
+
+ path, mime_type = client.Report(guid).get_blob_path('data')
+ self.assertEqual(None, path)
+ self.assertEqual(True, client.Report(guid).get_blob('data').closed)
+
+ def test_GetDefaultBLOB(self):
self.start_ipc_and_restful_server()
client = Client('/')
@@ -307,8 +321,8 @@ class RemoteMountTest(tests.Test):
description='description').post()
path, mime_type = client.Context(guid).get_blob_path('icon')
- self.assertEqual(None, path)
- self.assertEqual(True, client.Context(guid).get_blob('icon').closed)
+ assert exists(path)
+ self.assertEqual(False, client.Context(guid).get_blob('icon').closed)
def test_Localize(self):
os.environ['LANG'] = 'en_US'
diff --git a/tests/units/router.py b/tests/units/router.py
index f41ae10..b2daef8 100755
--- a/tests/units/router.py
+++ b/tests/units/router.py
@@ -224,13 +224,10 @@ class RouterTest(tests.Test):
self.fork(self.restful_server, [User, Document])
rest = tests.Request('http://localhost:8800')
- # Should `urllib.splithost('//foo')` return `('foo', '')` ?
- self.assertRaises(RuntimeError, rest.post, '//document/', {'term': 'probe'})
-
- guid = rest.post('/document//', {'term': 'probe'})
+ guid = rest.post('///document//', {'term': 'probe'})
self.assertEqual(
{'term': 'probe'},
- rest.get('///document//%s/' % guid, reply='term'))
+ rest.get('///document///%s///' % guid, reply='term'))
def test_HandleRedirects(self):
URL = 'http://sugarlabs.org'