Merge lp:~marcustomlinson/unity-js-scopes/filters_example into lp:unity-js-scopes

Proposed by Marcus Tomlinson on 2016-05-12
Status: Needs review
Proposed branch: lp:~marcustomlinson/unity-js-scopes/filters_example
Merge into: lp:unity-js-scopes
Diff against target: 904 lines (+800/-0)
10 files modified
examples/filters/CMakeLists.txt (+55/-0)
examples/filters/filters.apparmor (+7/-0)
examples/filters/manifest.json.in (+15/-0)
examples/filters/po/CMakeLists.txt (+15/-0)
examples/filters/po/POTFILES.in (+4/-0)
examples/filters/po/POTFILES.in.in (+4/-0)
examples/filters/src/CMakeLists.txt (+65/-0)
examples/filters/src/data/filters-settings.ini.in (+1/-0)
examples/filters/src/data/filters.ini.in (+7/-0)
examples/filters/src/filters.js (+627/-0)
To merge this branch: bzr merge lp:~marcustomlinson/unity-js-scopes/filters_example
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve on 2016-05-12
unity-api-1-bot continuous-integration Needs Fixing on 2016-05-12
WebApps 2016-05-12 Pending
Review via email: mp+294488@code.launchpad.net

Commit message

Added "filters" example scope

To post a comment you must log in.
144. By Marcus Tomlinson on 2016-05-12

Add missing copyright header

Unmerged revisions

144. By Marcus Tomlinson on 2016-05-12

Add missing copyright header

143. By Marcus Tomlinson on 2016-05-12

Added "filters" example scope

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory 'examples/filters'
2=== added file 'examples/filters/CMakeLists.txt'
3--- examples/filters/CMakeLists.txt 1970-01-01 00:00:00 +0000
4+++ examples/filters/CMakeLists.txt 2016-05-12 12:36:01 +0000
5@@ -0,0 +1,55 @@
6+project(filters)
7+cmake_minimum_required(VERSION 2.8.10)
8+
9+# This is required to ensure the correct node modules are included in the project
10+execute_process(COMMAND unity-js-scopes-tool reinstall ${CMAKE_SOURCE_DIR}/src/node_modules unity-js-scopes)
11+add_custom_target(build_modules ALL COMMAND unity-js-scopes-tool rebuild ${CMAKE_SOURCE_DIR}/src/node_modules)
12+
13+# Do not remove this, its required for the correct functionality of the Ubuntu-SDK
14+set(UBUNTU_MANIFEST_PATH "manifest.json.in" CACHE INTERNAL "Tells QtCreator location and name of the manifest file")
15+set(UBUNTU_PROJECT_TYPE "Scope" CACHE INTERNAL "Tells QtCreator this is a Scope project")
16+
17+# Important project paths
18+set(CMAKE_INSTALL_PREFIX /)
19+set(SCOPE_INSTALL_DIR "/filters")
20+set(GETTEXT_PACKAGE "filters")
21+set(PACKAGE_NAME "filters.marcustomlinson")
22+set(SCOPE_NAME "${PACKAGE_NAME}_filters")
23+
24+# This command figures out the target architecture and puts it into the manifest file
25+execute_process(
26+ COMMAND dpkg-architecture -qDEB_HOST_ARCH
27+ OUTPUT_VARIABLE CLICK_ARCH
28+ OUTPUT_STRIP_TRAILING_WHITESPACE
29+)
30+
31+# Install the manifest and apparmor files
32+configure_file(manifest.json.in ${CMAKE_CURRENT_BINARY_DIR}/manifest.json)
33+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/manifest.json DESTINATION "/")
34+install(FILES "filters.apparmor" DESTINATION "/")
35+
36+# Make these files show up in QtCreator
37+file(GLOB_RECURSE
38+ _PO_JS_FILES
39+ "po/*.po"
40+ "po/*.pot"
41+ "*.js"
42+)
43+add_custom_target(hidden_files
44+ ALL
45+ SOURCES
46+ manifest.json.in
47+ filters.apparmor
48+ src/data/filters.ini.in
49+ src/data/filters-settings.ini.in
50+ po/POTFILES.in.in
51+ ${_PO_JS_FILES}
52+)
53+
54+# Search for our dependencies
55+find_package(Intltool)
56+
57+# Add our main directories
58+add_subdirectory(po)
59+add_subdirectory(src)
60+
61
62=== added file 'examples/filters/filters.apparmor'
63--- examples/filters/filters.apparmor 1970-01-01 00:00:00 +0000
64+++ examples/filters/filters.apparmor 2016-05-12 12:36:01 +0000
65@@ -0,0 +1,7 @@
66+{
67+ "template": "ubuntu-scope-network",
68+ "policy_groups": [],
69+ "policy_version": 1.3
70+}
71+
72+
73
74=== added file 'examples/filters/manifest.json.in'
75--- examples/filters/manifest.json.in 1970-01-01 00:00:00 +0000
76+++ examples/filters/manifest.json.in 2016-05-12 12:36:01 +0000
77@@ -0,0 +1,15 @@
78+{
79+ "architecture": "@CLICK_ARCH@",
80+ "description": "A simple Unity scope written in JavaScript",
81+ "framework": "ubuntu-sdk-15.04.5",
82+ "hooks": {
83+ "filters": {
84+ "apparmor": "filters.apparmor",
85+ "scope": "filters"
86+ }
87+ },
88+ "maintainer": "Marcus Tomlinson <marcus.tomlinson@canonical.com>",
89+ "name": "filters.marcustomlinson",
90+ "title": "filters",
91+ "version": "0.1"
92+}
93
94=== added directory 'examples/filters/po'
95=== added file 'examples/filters/po/CMakeLists.txt'
96--- examples/filters/po/CMakeLists.txt 1970-01-01 00:00:00 +0000
97+++ examples/filters/po/CMakeLists.txt 2016-05-12 12:36:01 +0000
98@@ -0,0 +1,15 @@
99+intltool_update_potfile(
100+ ALL
101+ KEYWORDS "tr" "tr:1,2" "dtr:2" "dtr:2,3" "N_"
102+ COPYRIGHT_HOLDER ""
103+ POTFILES_TEMPLATE "POTFILES.in.in"
104+ GETTEXT_PACKAGE ${GETTEXT_PACKAGE}
105+)
106+
107+intltool_install_translations(
108+ ALL
109+ GETTEXT_PACKAGE ${GETTEXT_PACKAGE}
110+)
111+
112+
113+
114
115=== added file 'examples/filters/po/POTFILES.in'
116--- examples/filters/po/POTFILES.in 1970-01-01 00:00:00 +0000
117+++ examples/filters/po/POTFILES.in 2016-05-12 12:36:01 +0000
118@@ -0,0 +1,4 @@
119+[type: gettext/ini] src/data/filters.ini.in
120+[type: gettext/ini] src/data/filters-settings.ini.in
121+
122+
123
124=== added file 'examples/filters/po/POTFILES.in.in'
125--- examples/filters/po/POTFILES.in.in 1970-01-01 00:00:00 +0000
126+++ examples/filters/po/POTFILES.in.in 2016-05-12 12:36:01 +0000
127@@ -0,0 +1,4 @@
128+[type: gettext/ini] src/data/filters.ini.in
129+[type: gettext/ini] src/data/filters-settings.ini.in
130+@GENERATED_POTFILES@
131+
132
133=== added directory 'examples/filters/src'
134=== added file 'examples/filters/src/CMakeLists.txt'
135--- examples/filters/src/CMakeLists.txt 1970-01-01 00:00:00 +0000
136+++ examples/filters/src/CMakeLists.txt 2016-05-12 12:36:01 +0000
137@@ -0,0 +1,65 @@
138+# Put the ini, image, and js files in the build directory next
139+# to the scope .so file so test tools can find them easily.
140+intltool_merge_translations(
141+ "data/filters.ini.in"
142+ "${CMAKE_CURRENT_BINARY_DIR}/${SCOPE_NAME}.ini"
143+ ALL UTF8
144+)
145+intltool_merge_translations(
146+ "data/filters-settings.ini.in"
147+ "${CMAKE_CURRENT_BINARY_DIR}/${SCOPE_NAME}-settings.ini"
148+ ALL UTF8
149+)
150+
151+configure_file(
152+ "data/icon.png"
153+ "${CMAKE_CURRENT_BINARY_DIR}/icon.png"
154+ @ONLY COPYONLY
155+)
156+configure_file(
157+ "data/logo.png"
158+ "${CMAKE_CURRENT_BINARY_DIR}/logo.png"
159+ @ONLY COPYONLY
160+)
161+
162+configure_file(
163+ "filters.js"
164+ "${CMAKE_CURRENT_BINARY_DIR}/${SCOPE_NAME}.js"
165+ @ONLY COPYONLY
166+)
167+
168+add_custom_target(
169+ copy_modules ALL
170+ COMMAND ${CMAKE_COMMAND} -E create_symlink
171+ "${CMAKE_CURRENT_SOURCE_DIR}/node_modules"
172+ "${CMAKE_CURRENT_BINARY_DIR}/node_modules"
173+)
174+
175+add_custom_target(
176+ copy_covers ALL
177+ COMMAND ${CMAKE_COMMAND} -E create_symlink
178+ "${CMAKE_CURRENT_SOURCE_DIR}/data/covers"
179+ "${CMAKE_CURRENT_BINARY_DIR}/covers"
180+)
181+
182+# Install the scope ini, image, and js files
183+install(
184+ FILES
185+ "${CMAKE_CURRENT_BINARY_DIR}/${SCOPE_NAME}.ini"
186+ "${CMAKE_CURRENT_BINARY_DIR}/${SCOPE_NAME}-settings.ini"
187+ "${CMAKE_CURRENT_BINARY_DIR}/icon.png"
188+ "${CMAKE_CURRENT_BINARY_DIR}/logo.png"
189+ "${CMAKE_CURRENT_BINARY_DIR}/${SCOPE_NAME}.js"
190+ DESTINATION
191+ ${SCOPE_INSTALL_DIR}
192+)
193+
194+install(
195+ DIRECTORY
196+ "${CMAKE_CURRENT_SOURCE_DIR}/node_modules"
197+ "${CMAKE_CURRENT_SOURCE_DIR}/data/covers"
198+ DESTINATION
199+ ${SCOPE_INSTALL_DIR}
200+ USE_SOURCE_PERMISSIONS
201+)
202+
203
204=== added directory 'examples/filters/src/data'
205=== added directory 'examples/filters/src/data/covers'
206=== added directory 'examples/filters/src/data/covers/childrens'
207=== added file 'examples/filters/src/data/covers/childrens/1.jpg'
208Binary files examples/filters/src/data/covers/childrens/1.jpg 1970-01-01 00:00:00 +0000 and examples/filters/src/data/covers/childrens/1.jpg 2016-05-12 12:36:01 +0000 differ
209=== added file 'examples/filters/src/data/covers/childrens/10.jpg'
210Binary files examples/filters/src/data/covers/childrens/10.jpg 1970-01-01 00:00:00 +0000 and examples/filters/src/data/covers/childrens/10.jpg 2016-05-12 12:36:01 +0000 differ
211=== added file 'examples/filters/src/data/covers/childrens/2.jpg'
212Binary files examples/filters/src/data/covers/childrens/2.jpg 1970-01-01 00:00:00 +0000 and examples/filters/src/data/covers/childrens/2.jpg 2016-05-12 12:36:01 +0000 differ
213=== added file 'examples/filters/src/data/covers/childrens/3.jpg'
214Binary files examples/filters/src/data/covers/childrens/3.jpg 1970-01-01 00:00:00 +0000 and examples/filters/src/data/covers/childrens/3.jpg 2016-05-12 12:36:01 +0000 differ
215=== added file 'examples/filters/src/data/covers/childrens/4.jpg'
216Binary files examples/filters/src/data/covers/childrens/4.jpg 1970-01-01 00:00:00 +0000 and examples/filters/src/data/covers/childrens/4.jpg 2016-05-12 12:36:01 +0000 differ
217=== added file 'examples/filters/src/data/covers/childrens/5.jpg'
218Binary files examples/filters/src/data/covers/childrens/5.jpg 1970-01-01 00:00:00 +0000 and examples/filters/src/data/covers/childrens/5.jpg 2016-05-12 12:36:01 +0000 differ
219=== added file 'examples/filters/src/data/covers/childrens/6.jpg'
220Binary files examples/filters/src/data/covers/childrens/6.jpg 1970-01-01 00:00:00 +0000 and examples/filters/src/data/covers/childrens/6.jpg 2016-05-12 12:36:01 +0000 differ
221=== added file 'examples/filters/src/data/covers/childrens/7.jpg'
222Binary files examples/filters/src/data/covers/childrens/7.jpg 1970-01-01 00:00:00 +0000 and examples/filters/src/data/covers/childrens/7.jpg 2016-05-12 12:36:01 +0000 differ
223=== added file 'examples/filters/src/data/covers/childrens/8.jpg'
224Binary files examples/filters/src/data/covers/childrens/8.jpg 1970-01-01 00:00:00 +0000 and examples/filters/src/data/covers/childrens/8.jpg 2016-05-12 12:36:01 +0000 differ
225=== added file 'examples/filters/src/data/covers/childrens/9.jpg'
226Binary files examples/filters/src/data/covers/childrens/9.jpg 1970-01-01 00:00:00 +0000 and examples/filters/src/data/covers/childrens/9.jpg 2016-05-12 12:36:01 +0000 differ
227=== added directory 'examples/filters/src/data/covers/fiction'
228=== added file 'examples/filters/src/data/covers/fiction/1.jpg'
229Binary files examples/filters/src/data/covers/fiction/1.jpg 1970-01-01 00:00:00 +0000 and examples/filters/src/data/covers/fiction/1.jpg 2016-05-12 12:36:01 +0000 differ
230=== added file 'examples/filters/src/data/covers/fiction/10.jpg'
231Binary files examples/filters/src/data/covers/fiction/10.jpg 1970-01-01 00:00:00 +0000 and examples/filters/src/data/covers/fiction/10.jpg 2016-05-12 12:36:01 +0000 differ
232=== added file 'examples/filters/src/data/covers/fiction/11.jpg'
233Binary files examples/filters/src/data/covers/fiction/11.jpg 1970-01-01 00:00:00 +0000 and examples/filters/src/data/covers/fiction/11.jpg 2016-05-12 12:36:01 +0000 differ
234=== added file 'examples/filters/src/data/covers/fiction/12.jpg'
235Binary files examples/filters/src/data/covers/fiction/12.jpg 1970-01-01 00:00:00 +0000 and examples/filters/src/data/covers/fiction/12.jpg 2016-05-12 12:36:01 +0000 differ
236=== added file 'examples/filters/src/data/covers/fiction/2.jpg'
237Binary files examples/filters/src/data/covers/fiction/2.jpg 1970-01-01 00:00:00 +0000 and examples/filters/src/data/covers/fiction/2.jpg 2016-05-12 12:36:01 +0000 differ
238=== added file 'examples/filters/src/data/covers/fiction/3.jpg'
239Binary files examples/filters/src/data/covers/fiction/3.jpg 1970-01-01 00:00:00 +0000 and examples/filters/src/data/covers/fiction/3.jpg 2016-05-12 12:36:01 +0000 differ
240=== added file 'examples/filters/src/data/covers/fiction/4.jpg'
241Binary files examples/filters/src/data/covers/fiction/4.jpg 1970-01-01 00:00:00 +0000 and examples/filters/src/data/covers/fiction/4.jpg 2016-05-12 12:36:01 +0000 differ
242=== added file 'examples/filters/src/data/covers/fiction/5.jpg'
243Binary files examples/filters/src/data/covers/fiction/5.jpg 1970-01-01 00:00:00 +0000 and examples/filters/src/data/covers/fiction/5.jpg 2016-05-12 12:36:01 +0000 differ
244=== added file 'examples/filters/src/data/covers/fiction/6.jpg'
245Binary files examples/filters/src/data/covers/fiction/6.jpg 1970-01-01 00:00:00 +0000 and examples/filters/src/data/covers/fiction/6.jpg 2016-05-12 12:36:01 +0000 differ
246=== added file 'examples/filters/src/data/covers/fiction/7.jpg'
247Binary files examples/filters/src/data/covers/fiction/7.jpg 1970-01-01 00:00:00 +0000 and examples/filters/src/data/covers/fiction/7.jpg 2016-05-12 12:36:01 +0000 differ
248=== added file 'examples/filters/src/data/covers/fiction/8.jpg'
249Binary files examples/filters/src/data/covers/fiction/8.jpg 1970-01-01 00:00:00 +0000 and examples/filters/src/data/covers/fiction/8.jpg 2016-05-12 12:36:01 +0000 differ
250=== added file 'examples/filters/src/data/covers/fiction/9.jpg'
251Binary files examples/filters/src/data/covers/fiction/9.jpg 1970-01-01 00:00:00 +0000 and examples/filters/src/data/covers/fiction/9.jpg 2016-05-12 12:36:01 +0000 differ
252=== added file 'examples/filters/src/data/filters-settings.ini.in'
253--- examples/filters/src/data/filters-settings.ini.in 1970-01-01 00:00:00 +0000
254+++ examples/filters/src/data/filters-settings.ini.in 2016-05-12 12:36:01 +0000
255@@ -0,0 +1,1 @@
256+
257
258=== added file 'examples/filters/src/data/filters.ini.in'
259--- examples/filters/src/data/filters.ini.in 1970-01-01 00:00:00 +0000
260+++ examples/filters/src/data/filters.ini.in 2016-05-12 12:36:01 +0000
261@@ -0,0 +1,7 @@
262+[ScopeConfig]
263+ScopeRunner=./node_modules/unity-js-scopes/bin/unity-js-scopes-launcher %S %R
264+_DisplayName=Books (JavaScript)
265+_Description=This is a Books scope for testing purposes
266+Art=screenshot.png
267+Author = Canonical Ltd.
268+Icon = icon.png
269
270=== added file 'examples/filters/src/data/icon.png'
271Binary files examples/filters/src/data/icon.png 1970-01-01 00:00:00 +0000 and examples/filters/src/data/icon.png 2016-05-12 12:36:01 +0000 differ
272=== added file 'examples/filters/src/data/logo.png'
273Binary files examples/filters/src/data/logo.png 1970-01-01 00:00:00 +0000 and examples/filters/src/data/logo.png 2016-05-12 12:36:01 +0000 differ
274=== added file 'examples/filters/src/filters.js'
275--- examples/filters/src/filters.js 1970-01-01 00:00:00 +0000
276+++ examples/filters/src/filters.js 2016-05-12 12:36:01 +0000
277@@ -0,0 +1,627 @@
278+/*
279+ * Copyright 2016 Canonical Ltd.
280+ *
281+ * This file is part of unity-js-scopes.
282+ *
283+ * unity-js-scopes is free software; you can redistribute it and/or modify
284+ * it under the terms of the GNU General Public License as published by
285+ * the Free Software Foundation; version 3.
286+ *
287+ * unity-js-scopes is distributed in the hope that it will be useful,
288+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
289+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
290+ * GNU General Public License for more details.
291+ *
292+ * You should have received a copy of the GNU General Public License
293+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
294+ */
295+
296+var scopes = require('unity-js-scopes')
297+
298+var CATEGORY_TEMPLATE =
299+ {
300+ "schema-version": 1,
301+ "template": {
302+ "category-layout": "grid",
303+ "card-layout": "horizontal",
304+ "card-size": "medium"
305+ },
306+ "components": {
307+ "title": "title",
308+ "art" : {
309+ "field": "art"
310+ },
311+ "subtitle": "subtitle",
312+ "attributes": {
313+ "field": "attributes",
314+ "max-count": 2
315+ }
316+ }
317+}
318+
319+var books = [];
320+
321+function book(titlev, formatv, authorv, pricev, ratingv, departmentv, categoryv, synopsisv, artv)
322+{
323+ return {
324+ title: titlev,
325+ format: formatv,
326+ author: authorv,
327+ price: pricev,
328+ rating: ratingv,
329+ department: departmentv,
330+ category: categoryv,
331+ synopsis: synopsisv,
332+ art: artv,
333+ }
334+}
335+
336+books.push(book(
337+ "Your Heart is a Muscle the Size of a Fist",
338+ "hardback",
339+ "Sunil Yapa",
340+ 14.99,
341+ 3,
342+ "fiction",
343+ "bestseller",
344+ "A heart-stopping debut about protest and riot ...1999. Victor, homeless after a family tragedy, finds himself pounding the streets of Seattle with little meaning or purpose. He is the estranged son of the police chief of the city, and today his father is in charge of one of the largest protests in the history of Western democracy. But in a matter of hours reality will become a nightmare. Hordes of protesters - from all sections of society - will test the patience of the city's police force, and lives will be altered forever: two armed police officers will struggle to keep calm amid the threat of violence; a protester with a murderous past will make an unforgivable mistake; and a delegate from Sri Lanka will do whatever it takes to make it through the crowd to a meeting - a meeting that could dramatically change the fate of his country. In amongst the fray, Victor and his father are heading for a collision too. Your Heart is a Muscle the Size of a Fist, set during the World Trade Organization protests, is a deeply charged novel showcasing a distinct and exciting new literary voice.",
345+ "1.jpg"
346+ )
347+ );
348+
349+books.push(book(
350+ "Gold Fame Citrus",
351+ "hardback",
352+ "Claire Vaye Watkins",
353+ 16.99,
354+ 4,
355+ "fiction",
356+ "book of the month",
357+ "Desert sands have laid waste to the south-west of America. Las Vegas is buried. California - and anyone still there - is stranded. Any way out is severely restricted. But Luz and Ray are not leaving. They survive on water rations, black market fruit and each other's need. Luz needs Ray, and Ray must be needed. But then they cross paths with a mysterious child, and the thirst for a better future begins. It's said there's a man on the edge of the Dune Sea. He leads a camp of believers. He can find water. Venturing into this dry heart of darkness, Luz thinks she has found their saviour. For the will to survive taps hidden powers; and the needed, and the needy, will exploit it. Like Margaret Atwood, Claire Vaye Watkins uses dystopia to traverse the scarred frontier of the heart, exploring the myths we tell about others and ourselves. In her bare and brilliant prose, nature and human nature, conspiracy and cult, motherhood and manhood are played out across the vast, implacable desert.",
358+ "2.jpg"
359+ )
360+ );
361+
362+books.push(book(
363+ "Love + Hate: Stories and Essay",
364+ "paperback",
365+ "Hanif Kureishi",
366+ 9.99,
367+ 5,
368+ "fiction",
369+ "bestseller",
370+ "Hate skews reality even more than love. In the story of a Pakistani woman who has begun a new life in Paris, an essay about the writing of Kureishi's acclaimed film Le Week-End, and an account of Kafka's relationship with his father, readers will find Kureishi also exploring the topics that he continues to make new, and make his own: growing up and growing old; betrayal and loyalty; imagination and repression; marriage and fatherhood. The collection ends with a bravura piece of very personal reportage about the conman who stole Kureishi's life savings - a man who provoked both admiration and disgust, obsession and revulsion, love and hate.",
371+ "3.jpg"
372+ )
373+ );
374+
375+books.push(book(
376+ "The Book of Speculation",
377+ "audiobook",
378+ "Erika Swyler",
379+ 12.99,
380+ 4,
381+ "fiction",
382+ "bestseller",
383+ "Simon Watson lives alone on the Long Island Sound in his family home, a house perched on the edge of a cliff that is slowly crumbling into the sea. His parents are long dead, his mother having drowned in the water his house overlooks. His younger sister, Enola, works for a travelling carnival and seldom calls. On a day in late June, Simon receives a mysterious book from an antiquarian bookseller; it has been sent to him because it is inscribed with the name Verona Bonn, Simon's grandmother. The book tells the story of two doomed lovers who were part of a travelling circus more than two hundred years ago. The paper crackles with age as Simon turns the yellowed pages filled with notes and sketches. He is fascinated, yet as he reads Simon becomes increasingly unnerved. Why do so many women in his family drown on 24th July? And could Enola, who has suddenly turned up at home for the first time in years, risk the same terrible fate? As 24th July draws ever closer, Simon must unlock the mysteries of the book, and decode his family history, before it's too late.",
384+ "4.jpg"
385+ )
386+ );
387+
388+books.push(book(
389+ "Rush Oh!",
390+ "hardback",
391+ "Shirley Barrett",
392+ 14.99,
393+ 4,
394+ "fiction",
395+ "bestseller",
396+ "When Mary Davidson, the eldest daughter of a whaling family in Eden, New South Wales, sets out to chronicle the particularly difficult season of 1908, the story she tells is poignant and hilarious, filled with drama and misadventure. It's a season marked not only by the sparsity of whales and the vagaries of weather, but also by the arrival of John Beck, an itinerant whaleman with a murky past, on whom Mary promptly develops an all-consuming crush. But hers is not the only romance to blossom amidst the blubber ...Swinging from Mary's hopes and disappointments, both domestic and romantic, to the challenges that beset their tiny whaling operation, Rush Oh! is a celebration of an extraordinary episode in Australian history when a family of whalers formed a fond, unique alliance with a pod of frisky killer whales - and in particular, a killer whale named Tom.",
397+ "5.jpg"
398+ )
399+ );
400+
401+books.push(book(
402+ "The High Mountains of Portugal",
403+ "hardback",
404+ "Yann Martel",
405+ 18.99,
406+ 3,
407+ "fiction",
408+ "special edition",
409+ "Lost in Portugal. Lost to grief. With nothing but a chimpanzee. The extraordinary new novel from the author of Life of Pi. In Lisbon in 1904, a young man named Tomas discovers an old journal. It hints at the location of an extraordinary artefact that - if it exists - would redefine history. Travelling in one of Europe's earliest automobiles, he sets out in search of this treasure. Some thirty-five years later, a Portuguese pathologist finds himself at the centre of a murder mystery. Fifty years on, a Canadian senator takes refuge in northern Portugal, grieving the loss of his beloved wife. But he comes to his ancestral village with an unusual companion: a chimpanzee. Three stories. Three broken hearts. One exploration: what is a life without stories? The High Mountains of Portugal takes the reader on a road trip through Portugal in the last century - and through the human soul.",
410+ "6.jpg"
411+ )
412+ );
413+
414+books.push(book(
415+ "Rebel of the Sands",
416+ "audiobook",
417+ "Alwyn Hamilton",
418+ 7.99,
419+ 3,
420+ "fiction",
421+ "recommended",
422+ "Sold immediately at auction across the world, this phenomenal novel is the first in a trilogy packed with shooting contests, train robberies, festivals under the stars, powerful Djinni magic and an electrifying love story. This promises to be a global super lead. Tell me that and we'll go. Right now. Save ourselves and leave this place to burn. Tell me that's how you want your story to go and we'll write it straight across the sand.' Dustwalk is Amani's home. The desert sand is in her bones. But she wants to escape. More than a want. A need. Then a foreigner with no name turns up to save her life, and with him the chance to run. But to where? The desert plains are full of danger. Sand and blood are swirling, and the Sultan's enemies are on the rise.",
423+ "7.jpg"
424+ )
425+ );
426+
427+books.push(book(
428+ "More of Me",
429+ "paperback",
430+ "Kathryn Evans",
431+ 6.99,
432+ 4,
433+ "fiction",
434+ "special edition",
435+ "Teva seems normal. But at home she hides an impossible secret: 11 other Tevas. Because once a year, Teva splits into two, leaving a younger version of herself stuck at the same age, forced to watch the new Teva taking over her life. But at 16, Teva's had enough. She's going to fight for her future - even if that means fighting herself. Imagine all your friends growing up, moving on, and you being stuck in one year of your life...More of Me is an incredible, unforgettable story of identity, friendship, love and sacrifice.",
436+ "8.jpg"
437+ )
438+ );
439+
440+books.push(book(
441+ "How Hard Can Love be?",
442+ "paperback",
443+ "Holly Bourne",
444+ 7.99,
445+ 4,
446+ "fiction",
447+ "recommended",
448+ "Sorry, no synopsis is currently available.",
449+ "9.jpg"
450+ )
451+ );
452+
453+books.push(book(
454+ "How Not to Disappear",
455+ "hardback",
456+ "Clare Furniss",
457+ 12.99,
458+ 3,
459+ "fiction",
460+ "recommended",
461+ "Our memories are what make us who we are. Some are real. Some are made up. But they are the stories that tell us who we are. Without them we are nobody.Hattie's summer isn't going as planned. Her two best friends have abandoned her: Reuben has run off to Europe to 'find himself' and Kat is in Edinburgh with her new girlfriend. Meanwhile Hattie is stuck babysitting her twin siblings and dealing with endless drama around her mum's wedding. Oh, and she's also just discovered that she's pregnant with Reuben's baby...Then Gloria, Hattie's great-aunt who no one even knew existed, comes crashing into her life. Gloria's fiercely independent, rather too fond of a gin sling and is in the early stages of dementia. Together the two of them set out on a road trip of self-discovery - Gloria to finally confront the secrets of her past before they are erased from her memory forever and Hattie to face the hard choices that will determine her future...Non Pratt's Trouble meets Thelma and Louise with a touch of Elizabeth is Missing by Emma Healey, Clare Furniss' remarkable How Not To Disappear is an emotional rollercoaster of a novel that will make you laugh and break your heart.",
462+ "10.jpg"
463+ )
464+ );
465+
466+books.push(book(
467+ "Front Lines",
468+ "paperback",
469+ "Michael Grant",
470+ 7.99,
471+ 2,
472+ "fiction",
473+ "recommended",
474+ "Just when you thought Michael Grant's Gone series had taken us to the darkest limits of his imagination, the evil genius of YA fiction is back to take you to the Front Lines of terror. In the tradition of The Book Thie, Code Name Verity and Between Shades of Gray, Front Lines gives the experience of WWII a new immediacy while playing with the 'what ifs?' of history. It's WWII, but not as you remember it from history lessons! This time the girls aren't stitching socks for the brave boys at the front. Meet Rio Richilin and her friends Frangie Marr and Rainy Schulterman, three of the newest recruits in the US Armed Forces. They stand shoulder to shoulder with the boys from home as they take on Hitler's army. In the face of reluctant colonels and sceptical sergeants, the soldier girls must prove their guts, strength, and resourcefulness as soldiers. Rio has grown up in a world where men don't cry and girls are supposed to care only about 'money and looks'. But she has always known that there is something wrong with this system and something else in her. Far from home and in the battlefields, Rio discovers exactly who she is and what she can accomplish.",
475+ "11.jpg"
476+ )
477+ );
478+
479+books.push(book(
480+ "All the Rage",
481+ "paperback",
482+ "Courtney Summers",
483+ 17.99,
484+ 5,
485+ "fiction",
486+ "special edition",
487+ "The footsteps stop but the birds are still singing, singing about a girl who wakes up on a dirt road and doesn't know what happened to her the night before...' Romy Grey wears her lipstick like armour, ever since the night she was raped by Kellan Turner, the sheriff's son. Romy refuses to be a victim, but speaking up has cost her everything. No one wants to believe Kellan is not the golden boy they thought he was, and Romy has given up trying to make herself heard. But when another girl goes missing after a party, Romy must decide whether the cost of her silence might be more than she can bear.",
488+ "12.jpg"
489+ )
490+ );
491+
492+books.push(book(
493+ "Sticker Dolly Dressing Fashion Designer London Collection",
494+ "hardback",
495+ "Fiona Watt",
496+ 6.99,
497+ 2,
498+ "childrens",
499+ "recommended",
500+ "London is one of the great fashion capitals of the world, and this book, with over 350 stickers - including 150 to colour yourself - allows young creatives to research, plan and design their own fashion collections, inspired by the city. With hints and tips on how to choose colours, patterns and shapes that work together.",
501+ "1.jpg"
502+ )
503+ );
504+
505+books.push(book(
506+ "Waiting for Callback",
507+ "paperback",
508+ "Perdita Cargill",
509+ 6.99,
510+ 3,
511+ "childrens",
512+ "recommended",
513+ "Geek Girl meets Fame meets New Girl in this brilliantly funny new series! When Elektra is discovered by an acting agent, she imagines Oscar glory can't be far away, but instead lurches from one cringe-worthy moment to the next! Just how many times can you be rejected for the part of 'Dead Girl Number Three' without losing hope? And who knew that actors were actually supposed to be multi-lingual, play seven instruments and be trained in a variety of circus skills? Off-stage things aren't going well either - she's fallen out with her best friend, remains firmly in the friend-zone with her crush and her parents are driving her crazy. One way or another, Elektra's life is now spent waiting for the phone to ring - waiting for callback. Can an average girl-next-door like Elektra really make it in the world of luvvies and starlets?",
514+ "2.jpg"
515+ )
516+ );
517+
518+books.push(book(
519+ "Anna and the Swallow Man",
520+ "hardback",
521+ "Gavriel Savit",
522+ 9.99,
523+ 4,
524+ "childrens",
525+ "special edition",
526+ "Anna and the Swallow Man is a stunning, literary, and wholly original debut novel that tells a new WW2 story. Krakow, 1939, is no place to grow up. There are a million marching soldiers and a thousand barking dogs. And Anna Lania is just seven years old when the Germans take her father and suddenly, she's alone. Then she meets the Swallow Man. He is a mystery, strange and tall. And like Anna's missing father, he has a gift for languages: Polish, Russian, German, Yiddish, even Bird. When he summons a bright, beautiful swallow down to his hand to stop her from crying, Anna is entranced. Over the course of their travels together, Anna and the Swallow Man will dodge bombs, tame soldiers, and even, despite their better judgement, make a friend. But in a world gone mad, everything can prove dangerous...",
527+ "3.jpg"
528+ )
529+ );
530+
531+books.push(book(
532+ "Time Travelling with a Hamster",
533+ "paperback",
534+ "Ross Welford",
535+ 16.99,
536+ 3,
537+ "childrens",
538+ "bestseller",
539+ "A truly original debut novel from an extraordinarily talented new voice in children's books. Laugh, cry and wonder at this race-against-time story of a boy who travels back to 1984 to prevent a go-kart accident, and save his father's life...'My dad died twice. Once when he was thirty nine and again four years later when he was twelve. The first time had nothing to do with me. The second time definitely did, but I would never even have been there if it hadn't been for his 'time machine'...\" When Al Chaudhury discovers his late dad's time machine, he finds that going back to the 1980s requires daring and imagination. It also requires lies, theft, burglary, and setting his school on fire. All without losing his pet hamster, Alan Shearer...",
540+ "4.jpg"
541+ )
542+ );
543+
544+books.push(book(
545+ "The Long Haul",
546+ "paperback",
547+ "Jeff Kinney",
548+ 9.99,
549+ 3,
550+ "childrens",
551+ "recommended",
552+ "A family road trip is supposed to be a lot of fun ...unless, of course, you're the Heffleys. The journey starts off full of promise, then quickly takes several wrong turns. Gas station bathrooms, crazed seagulls, a fender bender, and a runaway pig - not exactly Greg Heffley's idea of a good time. But even the worst road trip can turn into an adventure - and this is one the Heffleys won't soon forget. Zoo-Wee-Mama! Includes exclusive bumper stickers!",
553+ "5.jpg"
554+ )
555+ );
556+
557+books.push(book(
558+ "Barry Loser Hates Half Term",
559+ "audiobook",
560+ "Jim Smith",
561+ 12.99,
562+ 4,
563+ "childrens",
564+ "recommended",
565+ "This is the seventh book in the brilliant Roald Dahl Funny Prize award-winning series Barry Loser. Suitable for fans of Diary of a Wimpy Kid and Tom Gates. It's only a few days into the half-term holidays and Barry's dad has already had enough of him! He's packing Barry off to Pirate Camp, the same one he used to be sent to every year. Barry's not impressed - he's not a baby anymore, so why should he have to go to a camp for kiddy winkles? But horrible things are a foot at Pirate Camp - it's been taken over by the villainous Morag, and now its future's in doubt. There's only one thing to do: Barry and his new friends Sally Bottom and Renard Dupont have to uncover the hidden treasure of Mogden Island...Join everyone's favourite Loser on his seventh hilarious adventure!",
566+ "6.jpg"
567+ )
568+ );
569+
570+books.push(book(
571+ "The Butterfly Club",
572+ "paperback",
573+ "Jacqueline Wilson",
574+ 9.99,
575+ 3,
576+ "childrens",
577+ "recommended",
578+ "Tina is a triplet, but she's always been the odd one out. Her sisters Phil and Maddie are bigger and stronger and better at just about everything. Luckily, they look after teeny-tiny Tina wherever they go - but when the girls start in scary, super-strict Miss Lovejoy's class, they're split up, and Tina has to fend for herself for the first time. Tina is horrified when she's paired up with angry bully Selma, who nobody wants to be friends with. But when Miss Lovejoy asks them to help her create a butterfly garden in the school playground, Tina discovers she doesn't always need her sisters - and that there's a lot more to Selma than first meets the eye. This is a beautiful, heartwarming story about friendship, confidence and becoming your own person, from the mega-bestselling author of Tracy Beaker, Hetty Feather and Sleepovers.",
579+ "7.jpg"
580+ )
581+ );
582+
583+books.push(book(
584+ "Over 100 Animal Doodles",
585+ "paperback",
586+ "Fiona Watt",
587+ 11.99,
588+ 4,
589+ "childrens",
590+ "recommended",
591+ "Lots of simple instructions that will allow children to draw a range of animals with satisfying results. Learn step-by-step, with diagrams that explain how to use simple shapes to create animals - then practise drawing them again and again, creating scenes.",
592+ "8.jpg"
593+ )
594+ );
595+
596+books.push(book(
597+ "Confessions of an Imaginary Friend",
598+ "audiobook",
599+ "Michelle Cuevas",
600+ 14.99,
601+ 3,
602+ "childrens",
603+ "bestseller",
604+ "Jacques Papier thinks that everyone hates him. After all, teachers ignore him when he raises his hand in class, nobody ever picks him for sports teams, and his sister, Fleur, keeps having to remind their parents to set a place for him at the dinner table. But then Jacques discovers an uncomfortable truth: He is NOT Fleur's brother; he's her imaginary friend! And so begins Jacques' quest for identity ...what do you do when you realise that the only reason you exist is because of someone else's imagination? The whimsical \"autobiography\" of an imaginary friend who doesn't know he's imaginary - perfect for fans of Toy Story, The Imaginary and Moone Boy.",
605+ "9.jpg"
606+ )
607+ );
608+
609+books.push(book(
610+ "Shaun the Sheep - the Farmer's Llamas",
611+ "paperback",
612+ "Aardman Animations Ltd",
613+ 16.99,
614+ 4,
615+ "childrens",
616+ "rook of the month",
617+ "When a mix-up at the auction leads to a surprise win, the Farmer brings his prize animals - a trio of llamas - home to the farm. Shaun is thrilled, but are the new residents a baaad influence? Based on a one-of, half-hour TV episode, this junior novel includes full-colour stills from the special.",
618+ "10.jpg"
619+ )
620+ );
621+
622+function match(book, query, department, format, categories, min_price, max_price, rating)
623+{
624+ if (department && book.department !== department)
625+ {
626+ return false;
627+ }
628+
629+ if (format && book.format !== format)
630+ {
631+ return false;
632+ }
633+
634+ if (categories.length && categories.indexOf(book.category) === -1)
635+ {
636+ return false;
637+ }
638+
639+ if (book.price < min_price || book.price > max_price)
640+ {
641+ return false;
642+ }
643+
644+ if (book.rating < rating)
645+ {
646+ return false;
647+ }
648+
649+ if (query && book.title.indexOf(query) === -1 && book.author.indexOf(query) === -1)
650+ {
651+ return false;
652+ }
653+
654+ return true;
655+}
656+
657+function generate_results(canned_query, reply, book_format, book_categories, min_price, max_price, rating)
658+{
659+ var query_string = canned_query.query_string();
660+ var dept_id = canned_query.department_id();
661+
662+ var show_single_cat = (dept_id);
663+
664+ rating = Math.round(rating);
665+
666+ var count = 0;
667+ if (show_single_cat) {
668+ for (var i = 0; i < books.length; i++)
669+ {
670+ if (match(books[i], query_string, dept_id, book_format, book_categories, min_price, max_price, rating)) {
671+ ++count;
672+ }
673+ }
674+ }
675+
676+ var category_renderer = new scopes.lib.CategoryRenderer(JSON.stringify(CATEGORY_TEMPLATE));
677+ var cat_single = reply.register_category("all", count + " Books", "", category_renderer);
678+ var cat_fiction = reply.register_category("fiction", "Fiction", "", category_renderer);
679+ var cat_children = reply.register_category("childrens", "Children", "", category_renderer);
680+
681+ for (var i = 0; i < books.length; i++)
682+ {
683+ book = books[i];
684+ if (match(book, query_string, dept_id, book_format, book_categories, min_price, max_price, rating)) {
685+ var cat;
686+ if (show_single_cat) {
687+ cat = cat_single;
688+ } else {
689+ if (book.department == "fiction") {
690+ cat = cat_fiction;
691+ } else {
692+ cat = cat_children;
693+ }
694+ }
695+ var res = new scopes.lib.CategorisedResult(cat);
696+ res.set_uri("uri" + count++);
697+ res.set_title(book.title);
698+ res.set_art(scopes.self.scope_directory + "/covers/" + book.department + "/" + book.art);
699+ res.set("subtitle", book.author);
700+ res.set("description", book.synopsis);
701+
702+ var rating_s = "☆ " + book.rating;
703+ var price_s = "£" + book.price;
704+
705+ res.set("price", price_s);
706+ res.set("rating", rating_s);
707+
708+ res.set("attributes", [{value: price_s}, {value: rating_s}]);
709+
710+ // Push the result
711+ if (!reply.push(res)) {
712+ return;
713+ }
714+ }
715+ }
716+}
717+
718+scopes.self.initialize(
719+ {}
720+ ,
721+ {
722+ run: function() {
723+ console.log('Running...')
724+ },
725+ start: function(scope_id) {
726+ console.log('Starting scope id: '
727+ + scope_id
728+ + ', '
729+ + scopes.self.scope_directory)
730+ },
731+ search: function(canned_query, metadata) {
732+ return new scopes.lib.SearchQuery(
733+ canned_query,
734+ metadata,
735+ // run
736+ function(search_reply) {
737+ var query_string = canned_query.query_string();
738+ var dept_id = canned_query.department_id();
739+ var filter_state = canned_query.filter_state();
740+
741+ // departments
742+ var root = new scopes.lib.Department("", canned_query, "All Books");
743+ root.add_subdepartment(new scopes.lib.Department("fiction", canned_query, "Fiction"));
744+ root.add_subdepartment(new scopes.lib.Department("childrens", canned_query, "Children's"));
745+ search_reply.register_departments(root);
746+
747+ var group = new scopes.lib.FilterGroup("group1", "Params");
748+ var price_filter = new scopes.lib.RangeInputFilter("price", "Min", "", "to", "Max", "", group);
749+ price_filter.set_title("Price range");
750+
751+ var rating_filter_labels = new scopes.lib.ValueSliderLabels("1", "5", [[2, "2"], [3, "3"], [4, "4"]]);
752+ var rating_filter = new scopes.lib.ValueSliderFilter("rating", 1, 5, 1, rating_filter_labels, group);
753+ rating_filter.set_title("Rating");
754+
755+ var category_filter = new scopes.lib.OptionSelectorFilter("bookcategory", "Top picks", true);
756+ category_filter.add_option("book of the month", "Book of the month");
757+ category_filter.add_option("bestseller", "Bestsellers");
758+ category_filter.add_option("special edition", "Special editions");
759+ category_filter.add_option("recommended", "Recommended");
760+
761+ var format_filter = new scopes.lib.OptionSelectorFilter("format", "Format", false);
762+ format_filter.add_option("hardback", "Hardcover");
763+ format_filter.add_option("paperback", "Paperback");
764+ format_filter.add_option("audiobook", "Audiobook");
765+
766+ var book_format = "";
767+ var book_categories = [];
768+ var min_price = 0;
769+ var max_price = 9999;
770+ var rating = 0;
771+
772+ search_reply.push([category_filter, format_filter, price_filter, rating_filter], filter_state);
773+
774+ // determine filter values
775+ var format = format_filter.active_options(filter_state);
776+ if (format.length)
777+ {
778+ book_format = format[0].id();
779+ }
780+
781+ if (price_filter.has_start_value(filter_state))
782+ {
783+ min_price = price_filter.start_value(filter_state);
784+ }
785+
786+ if (price_filter.has_end_value(filter_state))
787+ {
788+ max_price = price_filter.end_value(filter_state);
789+ }
790+
791+ if (rating_filter.has_value(filter_state))
792+ {
793+ rating = rating_filter.value(filter_state);
794+ }
795+
796+ if (category_filter.has_active_option(filter_state))
797+ {
798+ var cats = category_filter.active_options(filter_state);
799+ for (var i = 0; i < cats.length; i++)
800+ {
801+ book_categories.push(cats[i].id());
802+ }
803+ }
804+
805+ generate_results(canned_query, search_reply, book_format, book_categories, min_price, max_price, rating);
806+
807+ search_reply.finished();
808+ },
809+ // cancelled
810+ function() {
811+ });
812+ },
813+ preview: function(result, action_metadata) {
814+ return new scopes.lib.PreviewQuery(
815+ result,
816+ action_metadata,
817+ // run
818+ function(preview_reply) {
819+ var layout1col = new scopes.lib.ColumnLayout(1);
820+ var layout2col = new scopes.lib.ColumnLayout(2);
821+ var layout3col = new scopes.lib.ColumnLayout(3);
822+
823+ layout1col.add_column(["image", "header", "summary", "buttons"]);
824+
825+ layout2col.add_column(["image"]);
826+ layout2col.add_column(["header", "summary", "buttons"]);
827+
828+ layout3col.add_column(["image"]);
829+ layout3col.add_column(["header", "summary", "buttons"]);
830+ layout3col.add_column([]);
831+
832+ preview_reply.register_layout([layout1col, layout2col, layout3col]);
833+
834+ var header = new scopes.lib.PreviewWidget("header", "header");
835+ header.add_attribute_value(
836+ "attributes",
837+ [
838+ {
839+ "value": result.get("price")
840+ },
841+ {
842+ "value": result.get("rating")
843+ }
844+ ]
845+ );
846+ header.add_attribute_mapping("title", "title");
847+ header.add_attribute_mapping("subtitle", "subtitle");
848+
849+ var image = new scopes.lib.PreviewWidget("image", "image");
850+ image.add_attribute_mapping("source", "art");
851+
852+ var description = new scopes.lib.PreviewWidget("summary", "text");
853+ description.add_attribute_mapping("text", "description");
854+
855+ var buttons = new scopes.lib.PreviewWidget("buttons", "actions");
856+ buttons.add_attribute_value(
857+ "actions",
858+ [
859+ {
860+ "id": "close",
861+ "label": "Close"
862+ }
863+ ]
864+ );
865+
866+ preview_reply.push([image, header, description, buttons ]);
867+ preview_reply.finished();
868+
869+ },
870+ // cancelled
871+ function() {
872+ });
873+ },
874+ perform_action: function(result, metadata, widget_id, action_id) {
875+ return new scopes.lib.ActivationQuery(
876+ result,
877+ metadata,
878+ widget_id,
879+ action_id,
880+ // activate
881+ function() {
882+ var activation_response;
883+
884+ switch (action_id)
885+ {
886+ case 'close':
887+ activation_response = new scopes.lib.ActivationResponse(
888+ scopes.defs.ActivationResponseStatus.ShowDash);
889+ break;
890+ default:
891+ activation_response = new scopes.lib.ActivationResponse(
892+ scopes.defs.ActivationResponseStatus.NotHandled);
893+ break;
894+ }
895+
896+ return activation_response;
897+ },
898+ // cancelled
899+ function() {
900+ });
901+ }
902+ }
903+ );
904+

Subscribers

People subscribed via source and target branches

to all changes: