Merge lp:~scopecreator-team/scopecreator/rss-emblem into lp:scopecreator

Proposed by Chris Wayne
Status: Superseded
Proposed branch: lp:~scopecreator-team/scopecreator/rss-emblem
Merge into: lp:scopecreator
Diff against target: 5420 lines (+4942/-0)
75 files modified
CMakeLists.txt (+111/-0)
LICENSE (+674/-0)
cmake/FindGMock.cmake (+13/-0)
cmake/FindIntltool.cmake (+265/-0)
data/CMakeLists.txt (+12/-0)
data/feeds.json (+46/-0)
data/rss.canonical_rss.ini.in (+11/-0)
include/api/client.h (+84/-0)
include/api/config.h (+44/-0)
include/scope/localization.h (+39/-0)
include/scope/preview.h (+57/-0)
include/scope/query.h (+58/-0)
include/scope/scope.h (+70/-0)
manifest.json.in (+15/-0)
po/CMakeLists.txt (+10/-0)
po/Makefile.in.in (+1/-0)
po/POTFILES.in (+12/-0)
po/rss.pot (+26/-0)
readme.txt (+26/-0)
rss.apparmor (+7/-0)
src/CMakeLists.txt (+97/-0)
src/api/client.cpp (+271/-0)
src/scope/preview.cpp (+91/-0)
src/scope/query.cpp (+233/-0)
src/scope/scope.cpp (+77/-0)
tests/CMakeLists.txt (+42/-0)
tests/server/bbc/news/rss.xml (+40/-0)
tests/server/cnet/rss/all/index.xml (+2/-0)
tests/server/elpais/portada.xml (+73/-0)
tests/server/euronews/_partners/ubuntu/news.xml (+2/-0)
tests/server/server.py (+67/-0)
tests/server/vox/rss/index.xml (+113/-0)
tests/server/xataka/xataka2.xml (+6/-0)
tests/unit/CMakeLists.txt (+34/-0)
tests/unit/bbc/CMakeLists.txt (+31/-0)
tests/unit/bbc/feeds.json (+62/-0)
tests/unit/bbc/images/headerLogo.svg (+80/-0)
tests/unit/bbc/images/logo.svg (+60/-0)
tests/unit/bbc/rss.ssweeny_rss.ini.in (+11/-0)
tests/unit/cnet/CMakeLists.txt (+36/-0)
tests/unit/cnet/cache/.cheat-click (+1/-0)
tests/unit/cnet/feeds.json (+50/-0)
tests/unit/cnet/icon.svg (+92/-0)
tests/unit/cnet/images/default.svg (+322/-0)
tests/unit/cnet/renderer/carousel.json (+12/-0)
tests/unit/cnet/renderer/hgrid.json (+15/-0)
tests/unit/cnet/renderer/journal.json (+16/-0)
tests/unit/cnet/renderer/large.json (+14/-0)
tests/unit/cnet/renderer/wide-art.json (+13/-0)
tests/unit/cnet/rss.ssweeny_rss.ini.in (+11/-0)
tests/unit/elpais/CMakeLists.txt (+11/-0)
tests/unit/elpais/feeds.json (+6/-0)
tests/unit/elpais/scope.ini.in (+16/-0)
tests/unit/euronews/CMakeLists.txt (+23/-0)
tests/unit/euronews/feeds.json (+26/-0)
tests/unit/euronews/icon.svg (+92/-0)
tests/unit/euronews/images/default.svg (+322/-0)
tests/unit/euronews/renderer/carousel.json (+12/-0)
tests/unit/euronews/renderer/hgrid.json (+15/-0)
tests/unit/euronews/renderer/journal.json (+15/-0)
tests/unit/euronews/renderer/large.json (+14/-0)
tests/unit/euronews/renderer/wide-art.json (+13/-0)
tests/unit/euronews/rss-scope.ini.in (+12/-0)
tests/unit/scope/test-scope.cpp (+630/-0)
tests/unit/vox/CMakeLists.txt (+12/-0)
tests/unit/vox/feeds.json (+46/-0)
tests/unit/vox/rss.ssweeny_rss.ini.in (+11/-0)
tests/unit/xataka/CMakeLists.txt (+23/-0)
tests/unit/xataka/feeds.json (+6/-0)
tests/unit/xataka/renderer/carousel.json (+12/-0)
tests/unit/xataka/renderer/hgrid.json (+15/-0)
tests/unit/xataka/renderer/journal.json (+15/-0)
tests/unit/xataka/renderer/large.json (+14/-0)
tests/unit/xataka/renderer/wide-art.json (+13/-0)
tests/unit/xataka/rss-scope.ini.in (+13/-0)
To merge this branch: bzr merge lp:~scopecreator-team/scopecreator/rss-emblem
Reviewer Review Type Date Requested Status
Scopecreator Team Pending
Review via email: mp+259618@code.launchpad.net

This proposal has been superseded by a proposal from 2015-05-20.

To post a comment you must log in.

Unmerged revisions

11. By Chris Wayne

Add emblem

10. By Scott Sweeny

File rename was lost in a merge somewhere

9. By Scott Sweeny

Add license info

8. By Scott Sweeny

Merge in unit tests

7. By Scott Sweeny

We should be using Variants to set fields

6. By Scott Sweeny

Use readElementText() instead of text() for more robust text extraction.

5. By Scott Sweeny

Remove "News" category title since it doesn't always apply and would need to be translated

4. By Scott Sweeny

Don't try to register departments if we only have one.

3. By Scott Sweeny

Don't just accept any link as the article link

2. By Scott Sweeny

Should probably have Canonical in the canonical name

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added file 'CMakeLists.txt'
--- CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ CMakeLists.txt 2015-05-20 13:57:15 +0000
@@ -0,0 +1,111 @@
1project(rss CXX)
2cmake_minimum_required(VERSION 2.8.10)
3set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake" "${CMAKE_MODULE_PATH}")
4
5# We require g++ 4.9, to avoid ABI breakage with earlier version.
6set(cxx_version_required 4.9)
7if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
8 if (NOT CMAKE_CXX_COMPILER_VERSION MATCHES "^${cxx_version_required}")
9 message(FATAL_ERROR "g++ version must be ${cxx_version_required}!")
10 endif()
11endif()
12
13# Set strict and naggy C++ compiler flags, and enable C++11
14add_definitions(
15 -fno-permissive
16 -std=c++11
17 -pedantic
18 -Wall
19 -Wextra
20 -fPIC
21 -DQT_NO_KEYWORDS
22)
23
24include(GNUInstallDirs)
25find_package(PkgConfig)
26find_package(Intltool)
27
28# We depend on Boost for string trimming
29find_package(
30 Boost
31 REQUIRED
32)
33
34# Search for our dependencies
35pkg_check_modules(
36 SCOPE
37 libunity-scopes>=0.6.0
38 net-cpp>=1.1.0
39 REQUIRED
40)
41
42find_package(Qt5Core REQUIRED)
43include_directories(${Qt5Core_INCLUDE_DIRS})
44
45# Add our dependencies to the include paths
46include_directories(
47 "${CMAKE_SOURCE_DIR}/include"
48 ${Boost_INCLUDE_DIRS}
49 ${SCOPE_INCLUDE_DIRS}
50)
51
52# Do not remove this line, its required for the correct functionality of the Ubuntu-SDK
53set(UBUNTU_MANIFEST_PATH "manifest.json.in" CACHE INTERNAL "Tells QtCreator location and name of the manifest file")
54set(UBUNTU_PROJECT_TYPE "Scope" CACHE INTERNAL "Tells QtCreator this is a Scope project")
55
56# Important project paths
57set(CMAKE_INSTALL_PREFIX /)
58set(SCOPE_INSTALL_DIR "/rss")
59set(GETTEXT_PACKAGE "rss")
60set(PACKAGE_NAME "rss.canonical")
61set(SCOPE_NAME "${PACKAGE_NAME}_rss")
62
63# If we need to refer to the scope's name or package in code, these definitions will help
64
65add_definitions(-DPACKAGE_NAME="${PACKAGE_NAME}")
66add_definitions(-DSCOPE_NAME="${SCOPE_NAME}")
67add_definitions(-DGETTEXT_PACKAGE="${GETTEXT_PACKAGE}")
68
69#This command figures out the target architecture and puts it into the manifest file
70execute_process(
71 COMMAND dpkg-architecture -qDEB_HOST_ARCH
72 OUTPUT_VARIABLE CLICK_ARCH
73 OUTPUT_STRIP_TRAILING_WHITESPACE
74)
75
76configure_file(manifest.json.in ${CMAKE_CURRENT_BINARY_DIR}/manifest.json)
77
78# Install the click manifest
79install(FILES ${CMAKE_CURRENT_BINARY_DIR}/manifest.json DESTINATION "/")
80install(FILES "rss.apparmor" DESTINATION "/")
81
82# Make these files show up in QtCreator
83file(GLOB_RECURSE
84 _PO_FILES
85 "po/*.po"
86)
87add_custom_target(hidden_files
88 ALL
89 SOURCES
90 manifest.json.in
91 rss.apparmor
92 data/${SCOPE_NAME}.ini.in
93 data/feeds.json
94 po/POTFILES.in
95 po/${GETTEXT_PACKAGE}.pot
96 ${_PO_FILES}
97)
98
99# Add our main directories
100add_subdirectory(src)
101add_subdirectory(data)
102add_subdirectory(po)
103
104# Set up the tests
105enable_testing()
106add_subdirectory(tests)
107add_custom_target(
108 check
109 ${CMAKE_CTEST_COMMAND} --force-new-ctest-process --output-on-failure
110)
111
0112
=== added file 'LICENSE'
--- LICENSE 1970-01-01 00:00:00 +0000
+++ LICENSE 2015-05-20 13:57:15 +0000
@@ -0,0 +1,674 @@
1 GNU GENERAL PUBLIC LICENSE
2 Version 3, 29 June 2007
3
4 Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
5 Everyone is permitted to copy and distribute verbatim copies
6 of this license document, but changing it is not allowed.
7
8 Preamble
9
10 The GNU General Public License is a free, copyleft license for
11software and other kinds of works.
12
13 The licenses for most software and other practical works are designed
14to take away your freedom to share and change the works. By contrast,
15the GNU General Public License is intended to guarantee your freedom to
16share and change all versions of a program--to make sure it remains free
17software for all its users. We, the Free Software Foundation, use the
18GNU General Public License for most of our software; it applies also to
19any other work released this way by its authors. You can apply it to
20your programs, too.
21
22 When we speak of free software, we are referring to freedom, not
23price. Our General Public Licenses are designed to make sure that you
24have the freedom to distribute copies of free software (and charge for
25them if you wish), that you receive source code or can get it if you
26want it, that you can change the software or use pieces of it in new
27free programs, and that you know you can do these things.
28
29 To protect your rights, we need to prevent others from denying you
30these rights or asking you to surrender the rights. Therefore, you have
31certain responsibilities if you distribute copies of the software, or if
32you modify it: responsibilities to respect the freedom of others.
33
34 For example, if you distribute copies of such a program, whether
35gratis or for a fee, you must pass on to the recipients the same
36freedoms that you received. You must make sure that they, too, receive
37or can get the source code. And you must show them these terms so they
38know their rights.
39
40 Developers that use the GNU GPL protect your rights with two steps:
41(1) assert copyright on the software, and (2) offer you this License
42giving you legal permission to copy, distribute and/or modify it.
43
44 For the developers' and authors' protection, the GPL clearly explains
45that there is no warranty for this free software. For both users' and
46authors' sake, the GPL requires that modified versions be marked as
47changed, so that their problems will not be attributed erroneously to
48authors of previous versions.
49
50 Some devices are designed to deny users access to install or run
51modified versions of the software inside them, although the manufacturer
52can do so. This is fundamentally incompatible with the aim of
53protecting users' freedom to change the software. The systematic
54pattern of such abuse occurs in the area of products for individuals to
55use, which is precisely where it is most unacceptable. Therefore, we
56have designed this version of the GPL to prohibit the practice for those
57products. If such problems arise substantially in other domains, we
58stand ready to extend this provision to those domains in future versions
59of the GPL, as needed to protect the freedom of users.
60
61 Finally, every program is threatened constantly by software patents.
62States should not allow patents to restrict development and use of
63software on general-purpose computers, but in those that do, we wish to
64avoid the special danger that patents applied to a free program could
65make it effectively proprietary. To prevent this, the GPL assures that
66patents cannot be used to render the program non-free.
67
68 The precise terms and conditions for copying, distribution and
69modification follow.
70
71 TERMS AND CONDITIONS
72
73 0. Definitions.
74
75 "This License" refers to version 3 of the GNU General Public License.
76
77 "Copyright" also means copyright-like laws that apply to other kinds of
78works, such as semiconductor masks.
79
80 "The Program" refers to any copyrightable work licensed under this
81License. Each licensee is addressed as "you". "Licensees" and
82"recipients" may be individuals or organizations.
83
84 To "modify" a work means to copy from or adapt all or part of the work
85in a fashion requiring copyright permission, other than the making of an
86exact copy. The resulting work is called a "modified version" of the
87earlier work or a work "based on" the earlier work.
88
89 A "covered work" means either the unmodified Program or a work based
90on the Program.
91
92 To "propagate" a work means to do anything with it that, without
93permission, would make you directly or secondarily liable for
94infringement under applicable copyright law, except executing it on a
95computer or modifying a private copy. Propagation includes copying,
96distribution (with or without modification), making available to the
97public, and in some countries other activities as well.
98
99 To "convey" a work means any kind of propagation that enables other
100parties to make or receive copies. Mere interaction with a user through
101a computer network, with no transfer of a copy, is not conveying.
102
103 An interactive user interface displays "Appropriate Legal Notices"
104to the extent that it includes a convenient and prominently visible
105feature that (1) displays an appropriate copyright notice, and (2)
106tells the user that there is no warranty for the work (except to the
107extent that warranties are provided), that licensees may convey the
108work under this License, and how to view a copy of this License. If
109the interface presents a list of user commands or options, such as a
110menu, a prominent item in the list meets this criterion.
111
112 1. Source Code.
113
114 The "source code" for a work means the preferred form of the work
115for making modifications to it. "Object code" means any non-source
116form of a work.
117
118 A "Standard Interface" means an interface that either is an official
119standard defined by a recognized standards body, or, in the case of
120interfaces specified for a particular programming language, one that
121is widely used among developers working in that language.
122
123 The "System Libraries" of an executable work include anything, other
124than the work as a whole, that (a) is included in the normal form of
125packaging a Major Component, but which is not part of that Major
126Component, and (b) serves only to enable use of the work with that
127Major Component, or to implement a Standard Interface for which an
128implementation is available to the public in source code form. A
129"Major Component", in this context, means a major essential component
130(kernel, window system, and so on) of the specific operating system
131(if any) on which the executable work runs, or a compiler used to
132produce the work, or an object code interpreter used to run it.
133
134 The "Corresponding Source" for a work in object code form means all
135the source code needed to generate, install, and (for an executable
136work) run the object code and to modify the work, including scripts to
137control those activities. However, it does not include the work's
138System Libraries, or general-purpose tools or generally available free
139programs which are used unmodified in performing those activities but
140which are not part of the work. For example, Corresponding Source
141includes interface definition files associated with source files for
142the work, and the source code for shared libraries and dynamically
143linked subprograms that the work is specifically designed to require,
144such as by intimate data communication or control flow between those
145subprograms and other parts of the work.
146
147 The Corresponding Source need not include anything that users
148can regenerate automatically from other parts of the Corresponding
149Source.
150
151 The Corresponding Source for a work in source code form is that
152same work.
153
154 2. Basic Permissions.
155
156 All rights granted under this License are granted for the term of
157copyright on the Program, and are irrevocable provided the stated
158conditions are met. This License explicitly affirms your unlimited
159permission to run the unmodified Program. The output from running a
160covered work is covered by this License only if the output, given its
161content, constitutes a covered work. This License acknowledges your
162rights of fair use or other equivalent, as provided by copyright law.
163
164 You may make, run and propagate covered works that you do not
165convey, without conditions so long as your license otherwise remains
166in force. You may convey covered works to others for the sole purpose
167of having them make modifications exclusively for you, or provide you
168with facilities for running those works, provided that you comply with
169the terms of this License in conveying all material for which you do
170not control copyright. Those thus making or running the covered works
171for you must do so exclusively on your behalf, under your direction
172and control, on terms that prohibit them from making any copies of
173your copyrighted material outside their relationship with you.
174
175 Conveying under any other circumstances is permitted solely under
176the conditions stated below. Sublicensing is not allowed; section 10
177makes it unnecessary.
178
179 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180
181 No covered work shall be deemed part of an effective technological
182measure under any applicable law fulfilling obligations under article
18311 of the WIPO copyright treaty adopted on 20 December 1996, or
184similar laws prohibiting or restricting circumvention of such
185measures.
186
187 When you convey a covered work, you waive any legal power to forbid
188circumvention of technological measures to the extent such circumvention
189is effected by exercising rights under this License with respect to
190the covered work, and you disclaim any intention to limit operation or
191modification of the work as a means of enforcing, against the work's
192users, your or third parties' legal rights to forbid circumvention of
193technological measures.
194
195 4. Conveying Verbatim Copies.
196
197 You may convey verbatim copies of the Program's source code as you
198receive it, in any medium, provided that you conspicuously and
199appropriately publish on each copy an appropriate copyright notice;
200keep intact all notices stating that this License and any
201non-permissive terms added in accord with section 7 apply to the code;
202keep intact all notices of the absence of any warranty; and give all
203recipients a copy of this License along with the Program.
204
205 You may charge any price or no price for each copy that you convey,
206and you may offer support or warranty protection for a fee.
207
208 5. Conveying Modified Source Versions.
209
210 You may convey a work based on the Program, or the modifications to
211produce it from the Program, in the form of source code under the
212terms of section 4, provided that you also meet all of these conditions:
213
214 a) The work must carry prominent notices stating that you modified
215 it, and giving a relevant date.
216
217 b) The work must carry prominent notices stating that it is
218 released under this License and any conditions added under section
219 7. This requirement modifies the requirement in section 4 to
220 "keep intact all notices".
221
222 c) You must license the entire work, as a whole, under this
223 License to anyone who comes into possession of a copy. This
224 License will therefore apply, along with any applicable section 7
225 additional terms, to the whole of the work, and all its parts,
226 regardless of how they are packaged. This License gives no
227 permission to license the work in any other way, but it does not
228 invalidate such permission if you have separately received it.
229
230 d) If the work has interactive user interfaces, each must display
231 Appropriate Legal Notices; however, if the Program has interactive
232 interfaces that do not display Appropriate Legal Notices, your
233 work need not make them do so.
234
235 A compilation of a covered work with other separate and independent
236works, which are not by their nature extensions of the covered work,
237and which are not combined with it such as to form a larger program,
238in or on a volume of a storage or distribution medium, is called an
239"aggregate" if the compilation and its resulting copyright are not
240used to limit the access or legal rights of the compilation's users
241beyond what the individual works permit. Inclusion of a covered work
242in an aggregate does not cause this License to apply to the other
243parts of the aggregate.
244
245 6. Conveying Non-Source Forms.
246
247 You may convey a covered work in object code form under the terms
248of sections 4 and 5, provided that you also convey the
249machine-readable Corresponding Source under the terms of this License,
250in one of these ways:
251
252 a) Convey the object code in, or embodied in, a physical product
253 (including a physical distribution medium), accompanied by the
254 Corresponding Source fixed on a durable physical medium
255 customarily used for software interchange.
256
257 b) Convey the object code in, or embodied in, a physical product
258 (including a physical distribution medium), accompanied by a
259 written offer, valid for at least three years and valid for as
260 long as you offer spare parts or customer support for that product
261 model, to give anyone who possesses the object code either (1) a
262 copy of the Corresponding Source for all the software in the
263 product that is covered by this License, on a durable physical
264 medium customarily used for software interchange, for a price no
265 more than your reasonable cost of physically performing this
266 conveying of source, or (2) access to copy the
267 Corresponding Source from a network server at no charge.
268
269 c) Convey individual copies of the object code with a copy of the
270 written offer to provide the Corresponding Source. This
271 alternative is allowed only occasionally and noncommercially, and
272 only if you received the object code with such an offer, in accord
273 with subsection 6b.
274
275 d) Convey the object code by offering access from a designated
276 place (gratis or for a charge), and offer equivalent access to the
277 Corresponding Source in the same way through the same place at no
278 further charge. You need not require recipients to copy the
279 Corresponding Source along with the object code. If the place to
280 copy the object code is a network server, the Corresponding Source
281 may be on a different server (operated by you or a third party)
282 that supports equivalent copying facilities, provided you maintain
283 clear directions next to the object code saying where to find the
284 Corresponding Source. Regardless of what server hosts the
285 Corresponding Source, you remain obligated to ensure that it is
286 available for as long as needed to satisfy these requirements.
287
288 e) Convey the object code using peer-to-peer transmission, provided
289 you inform other peers where the object code and Corresponding
290 Source of the work are being offered to the general public at no
291 charge under subsection 6d.
292
293 A separable portion of the object code, whose source code is excluded
294from the Corresponding Source as a System Library, need not be
295included in conveying the object code work.
296
297 A "User Product" is either (1) a "consumer product", which means any
298tangible personal property which is normally used for personal, family,
299or household purposes, or (2) anything designed or sold for incorporation
300into a dwelling. In determining whether a product is a consumer product,
301doubtful cases shall be resolved in favor of coverage. For a particular
302product received by a particular user, "normally used" refers to a
303typical or common use of that class of product, regardless of the status
304of the particular user or of the way in which the particular user
305actually uses, or expects or is expected to use, the product. A product
306is a consumer product regardless of whether the product has substantial
307commercial, industrial or non-consumer uses, unless such uses represent
308the only significant mode of use of the product.
309
310 "Installation Information" for a User Product means any methods,
311procedures, authorization keys, or other information required to install
312and execute modified versions of a covered work in that User Product from
313a modified version of its Corresponding Source. The information must
314suffice to ensure that the continued functioning of the modified object
315code is in no case prevented or interfered with solely because
316modification has been made.
317
318 If you convey an object code work under this section in, or with, or
319specifically for use in, a User Product, and the conveying occurs as
320part of a transaction in which the right of possession and use of the
321User Product is transferred to the recipient in perpetuity or for a
322fixed term (regardless of how the transaction is characterized), the
323Corresponding Source conveyed under this section must be accompanied
324by the Installation Information. But this requirement does not apply
325if neither you nor any third party retains the ability to install
326modified object code on the User Product (for example, the work has
327been installed in ROM).
328
329 The requirement to provide Installation Information does not include a
330requirement to continue to provide support service, warranty, or updates
331for a work that has been modified or installed by the recipient, or for
332the User Product in which it has been modified or installed. Access to a
333network may be denied when the modification itself materially and
334adversely affects the operation of the network or violates the rules and
335protocols for communication across the network.
336
337 Corresponding Source conveyed, and Installation Information provided,
338in accord with this section must be in a format that is publicly
339documented (and with an implementation available to the public in
340source code form), and must require no special password or key for
341unpacking, reading or copying.
342
343 7. Additional Terms.
344
345 "Additional permissions" are terms that supplement the terms of this
346License by making exceptions from one or more of its conditions.
347Additional permissions that are applicable to the entire Program shall
348be treated as though they were included in this License, to the extent
349that they are valid under applicable law. If additional permissions
350apply only to part of the Program, that part may be used separately
351under those permissions, but the entire Program remains governed by
352this License without regard to the additional permissions.
353
354 When you convey a copy of a covered work, you may at your option
355remove any additional permissions from that copy, or from any part of
356it. (Additional permissions may be written to require their own
357removal in certain cases when you modify the work.) You may place
358additional permissions on material, added by you to a covered work,
359for which you have or can give appropriate copyright permission.
360
361 Notwithstanding any other provision of this License, for material you
362add to a covered work, you may (if authorized by the copyright holders of
363that material) supplement the terms of this License with terms:
364
365 a) Disclaiming warranty or limiting liability differently from the
366 terms of sections 15 and 16 of this License; or
367
368 b) Requiring preservation of specified reasonable legal notices or
369 author attributions in that material or in the Appropriate Legal
370 Notices displayed by works containing it; or
371
372 c) Prohibiting misrepresentation of the origin of that material, or
373 requiring that modified versions of such material be marked in
374 reasonable ways as different from the original version; or
375
376 d) Limiting the use for publicity purposes of names of licensors or
377 authors of the material; or
378
379 e) Declining to grant rights under trademark law for use of some
380 trade names, trademarks, or service marks; or
381
382 f) Requiring indemnification of licensors and authors of that
383 material by anyone who conveys the material (or modified versions of
384 it) with contractual assumptions of liability to the recipient, for
385 any liability that these contractual assumptions directly impose on
386 those licensors and authors.
387
388 All other non-permissive additional terms are considered "further
389restrictions" within the meaning of section 10. If the Program as you
390received it, or any part of it, contains a notice stating that it is
391governed by this License along with a term that is a further
392restriction, you may remove that term. If a license document contains
393a further restriction but permits relicensing or conveying under this
394License, you may add to a covered work material governed by the terms
395of that license document, provided that the further restriction does
396not survive such relicensing or conveying.
397
398 If you add terms to a covered work in accord with this section, you
399must place, in the relevant source files, a statement of the
400additional terms that apply to those files, or a notice indicating
401where to find the applicable terms.
402
403 Additional terms, permissive or non-permissive, may be stated in the
404form of a separately written license, or stated as exceptions;
405the above requirements apply either way.
406
407 8. Termination.
408
409 You may not propagate or modify a covered work except as expressly
410provided under this License. Any attempt otherwise to propagate or
411modify it is void, and will automatically terminate your rights under
412this License (including any patent licenses granted under the third
413paragraph of section 11).
414
415 However, if you cease all violation of this License, then your
416license from a particular copyright holder is reinstated (a)
417provisionally, unless and until the copyright holder explicitly and
418finally terminates your license, and (b) permanently, if the copyright
419holder fails to notify you of the violation by some reasonable means
420prior to 60 days after the cessation.
421
422 Moreover, your license from a particular copyright holder is
423reinstated permanently if the copyright holder notifies you of the
424violation by some reasonable means, this is the first time you have
425received notice of violation of this License (for any work) from that
426copyright holder, and you cure the violation prior to 30 days after
427your receipt of the notice.
428
429 Termination of your rights under this section does not terminate the
430licenses of parties who have received copies or rights from you under
431this License. If your rights have been terminated and not permanently
432reinstated, you do not qualify to receive new licenses for the same
433material under section 10.
434
435 9. Acceptance Not Required for Having Copies.
436
437 You are not required to accept this License in order to receive or
438run a copy of the Program. Ancillary propagation of a covered work
439occurring solely as a consequence of using peer-to-peer transmission
440to receive a copy likewise does not require acceptance. However,
441nothing other than this License grants you permission to propagate or
442modify any covered work. These actions infringe copyright if you do
443not accept this License. Therefore, by modifying or propagating a
444covered work, you indicate your acceptance of this License to do so.
445
446 10. Automatic Licensing of Downstream Recipients.
447
448 Each time you convey a covered work, the recipient automatically
449receives a license from the original licensors, to run, modify and
450propagate that work, subject to this License. You are not responsible
451for enforcing compliance by third parties with this License.
452
453 An "entity transaction" is a transaction transferring control of an
454organization, or substantially all assets of one, or subdividing an
455organization, or merging organizations. If propagation of a covered
456work results from an entity transaction, each party to that
457transaction who receives a copy of the work also receives whatever
458licenses to the work the party's predecessor in interest had or could
459give under the previous paragraph, plus a right to possession of the
460Corresponding Source of the work from the predecessor in interest, if
461the predecessor has it or can get it with reasonable efforts.
462
463 You may not impose any further restrictions on the exercise of the
464rights granted or affirmed under this License. For example, you may
465not impose a license fee, royalty, or other charge for exercise of
466rights granted under this License, and you may not initiate litigation
467(including a cross-claim or counterclaim in a lawsuit) alleging that
468any patent claim is infringed by making, using, selling, offering for
469sale, or importing the Program or any portion of it.
470
471 11. Patents.
472
473 A "contributor" is a copyright holder who authorizes use under this
474License of the Program or a work on which the Program is based. The
475work thus licensed is called the contributor's "contributor version".
476
477 A contributor's "essential patent claims" are all patent claims
478owned or controlled by the contributor, whether already acquired or
479hereafter acquired, that would be infringed by some manner, permitted
480by this License, of making, using, or selling its contributor version,
481but do not include claims that would be infringed only as a
482consequence of further modification of the contributor version. For
483purposes of this definition, "control" includes the right to grant
484patent sublicenses in a manner consistent with the requirements of
485this License.
486
487 Each contributor grants you a non-exclusive, worldwide, royalty-free
488patent license under the contributor's essential patent claims, to
489make, use, sell, offer for sale, import and otherwise run, modify and
490propagate the contents of its contributor version.
491
492 In the following three paragraphs, a "patent license" is any express
493agreement or commitment, however denominated, not to enforce a patent
494(such as an express permission to practice a patent or covenant not to
495sue for patent infringement). To "grant" such a patent license to a
496party means to make such an agreement or commitment not to enforce a
497patent against the party.
498
499 If you convey a covered work, knowingly relying on a patent license,
500and the Corresponding Source of the work is not available for anyone
501to copy, free of charge and under the terms of this License, through a
502publicly available network server or other readily accessible means,
503then you must either (1) cause the Corresponding Source to be so
504available, or (2) arrange to deprive yourself of the benefit of the
505patent license for this particular work, or (3) arrange, in a manner
506consistent with the requirements of this License, to extend the patent
507license to downstream recipients. "Knowingly relying" means you have
508actual knowledge that, but for the patent license, your conveying the
509covered work in a country, or your recipient's use of the covered work
510in a country, would infringe one or more identifiable patents in that
511country that you have reason to believe are valid.
512
513 If, pursuant to or in connection with a single transaction or
514arrangement, you convey, or propagate by procuring conveyance of, a
515covered work, and grant a patent license to some of the parties
516receiving the covered work authorizing them to use, propagate, modify
517or convey a specific copy of the covered work, then the patent license
518you grant is automatically extended to all recipients of the covered
519work and works based on it.
520
521 A patent license is "discriminatory" if it does not include within
522the scope of its coverage, prohibits the exercise of, or is
523conditioned on the non-exercise of one or more of the rights that are
524specifically granted under this License. You may not convey a covered
525work if you are a party to an arrangement with a third party that is
526in the business of distributing software, under which you make payment
527to the third party based on the extent of your activity of conveying
528the work, and under which the third party grants, to any of the
529parties who would receive the covered work from you, a discriminatory
530patent license (a) in connection with copies of the covered work
531conveyed by you (or copies made from those copies), or (b) primarily
532for and in connection with specific products or compilations that
533contain the covered work, unless you entered into that arrangement,
534or that patent license was granted, prior to 28 March 2007.
535
536 Nothing in this License shall be construed as excluding or limiting
537any implied license or other defenses to infringement that may
538otherwise be available to you under applicable patent law.
539
540 12. No Surrender of Others' Freedom.
541
542 If conditions are imposed on you (whether by court order, agreement or
543otherwise) that contradict the conditions of this License, they do not
544excuse you from the conditions of this License. If you cannot convey a
545covered work so as to satisfy simultaneously your obligations under this
546License and any other pertinent obligations, then as a consequence you may
547not convey it at all. For example, if you agree to terms that obligate you
548to collect a royalty for further conveying from those to whom you convey
549the Program, the only way you could satisfy both those terms and this
550License would be to refrain entirely from conveying the Program.
551
552 13. Use with the GNU Affero General Public License.
553
554 Notwithstanding any other provision of this License, you have
555permission to link or combine any covered work with a work licensed
556under version 3 of the GNU Affero General Public License into a single
557combined work, and to convey the resulting work. The terms of this
558License will continue to apply to the part which is the covered work,
559but the special requirements of the GNU Affero General Public License,
560section 13, concerning interaction through a network will apply to the
561combination as such.
562
563 14. Revised Versions of this License.
564
565 The Free Software Foundation may publish revised and/or new versions of
566the GNU General Public License from time to time. Such new versions will
567be similar in spirit to the present version, but may differ in detail to
568address new problems or concerns.
569
570 Each version is given a distinguishing version number. If the
571Program specifies that a certain numbered version of the GNU General
572Public License "or any later version" applies to it, you have the
573option of following the terms and conditions either of that numbered
574version or of any later version published by the Free Software
575Foundation. If the Program does not specify a version number of the
576GNU General Public License, you may choose any version ever published
577by the Free Software Foundation.
578
579 If the Program specifies that a proxy can decide which future
580versions of the GNU General Public License can be used, that proxy's
581public statement of acceptance of a version permanently authorizes you
582to choose that version for the Program.
583
584 Later license versions may give you additional or different
585permissions. However, no additional obligations are imposed on any
586author or copyright holder as a result of your choosing to follow a
587later version.
588
589 15. Disclaimer of Warranty.
590
591 THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599
600 16. Limitation of Liability.
601
602 IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610SUCH DAMAGES.
611
612 17. Interpretation of Sections 15 and 16.
613
614 If the disclaimer of warranty and limitation of liability provided
615above cannot be given local legal effect according to their terms,
616reviewing courts shall apply local law that most closely approximates
617an absolute waiver of all civil liability in connection with the
618Program, unless a warranty or assumption of liability accompanies a
619copy of the Program in return for a fee.
620
621 END OF TERMS AND CONDITIONS
622
623 How to Apply These Terms to Your New Programs
624
625 If you develop a new program, and you want it to be of the greatest
626possible use to the public, the best way to achieve this is to make it
627free software which everyone can redistribute and change under these terms.
628
629 To do so, attach the following notices to the program. It is safest
630to attach them to the start of each source file to most effectively
631state the exclusion of warranty; and each file should have at least
632the "copyright" line and a pointer to where the full notice is found.
633
634 <one line to give the program's name and a brief idea of what it does.>
635 Copyright (C) <year> <name of author>
636
637 This program is free software: you can redistribute it and/or modify
638 it under the terms of the GNU General Public License as published by
639 the Free Software Foundation, either version 3 of the License, or
640 (at your option) any later version.
641
642 This program is distributed in the hope that it will be useful,
643 but WITHOUT ANY WARRANTY; without even the implied warranty of
644 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645 GNU General Public License for more details.
646
647 You should have received a copy of the GNU General Public License
648 along with this program. If not, see <http://www.gnu.org/licenses/>.
649
650Also add information on how to contact you by electronic and paper mail.
651
652 If the program does terminal interaction, make it output a short
653notice like this when it starts in an interactive mode:
654
655 <program> Copyright (C) <year> <name of author>
656 This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657 This is free software, and you are welcome to redistribute it
658 under certain conditions; type `show c' for details.
659
660The hypothetical commands `show w' and `show c' should show the appropriate
661parts of the General Public License. Of course, your program's commands
662might be different; for a GUI interface, you would use an "about box".
663
664 You should also get your employer (if you work as a programmer) or school,
665if any, to sign a "copyright disclaimer" for the program, if necessary.
666For more information on this, and how to apply and follow the GNU GPL, see
667<http://www.gnu.org/licenses/>.
668
669 The GNU General Public License does not permit incorporating your program
670into proprietary programs. If your program is a subroutine library, you
671may consider it more useful to permit linking proprietary applications with
672the library. If this is what you want to do, use the GNU Lesser General
673Public License instead of this License. But first, please read
674<http://www.gnu.org/philosophy/why-not-lgpl.html>.
0675
=== added directory 'cmake'
=== added file 'cmake/FindGMock.cmake'
--- cmake/FindGMock.cmake 1970-01-01 00:00:00 +0000
+++ cmake/FindGMock.cmake 2015-05-20 13:57:15 +0000
@@ -0,0 +1,13 @@
1# Build with system gmock and embedded gtest
2set (GMOCK_INCLUDE_DIRS "/usr/include/gmock/include" CACHE PATH "gmock source include directory")
3set (GMOCK_SOURCE_DIR "/usr/src/gmock" CACHE PATH "gmock source directory")
4set (GTEST_INCLUDE_DIRS "${GMOCK_SOURCE_DIR}/gtest/include" CACHE PATH "gtest source include directory")
5
6add_subdirectory(${GMOCK_SOURCE_DIR} "${CMAKE_CURRENT_BINARY_DIR}/gmock")
7
8set(GTEST_LIBRARIES gtest)
9set(GTEST_MAIN_LIBRARIES gtest_main)
10set(GMOCK_LIBRARIES gmock gmock_main)
11
12set(GTEST_BOTH_LIBRARIES ${GTEST_LIBRARIES} ${GTEST_MAIN_LIBRARIES})
13
014
=== added file 'cmake/FindIntltool.cmake'
--- cmake/FindIntltool.cmake 1970-01-01 00:00:00 +0000
+++ cmake/FindIntltool.cmake 2015-05-20 13:57:15 +0000
@@ -0,0 +1,265 @@
1# Copyright (C) 2014 Canonical Ltd
2#
3# This program is free software: you can redistribute it and/or modify
4# it under the terms of the GNU Lesser General Public License version 3 as
5# published by the Free Software Foundation.
6#
7# This program is distributed in the hope that it will be useful,
8# but WITHOUT ANY WARRANTY; without even the implied warranty of
9# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10# GNU Lesser General Public License for more details.
11#
12# You should have received a copy of the GNU Lesser General Public License
13# along with this program. If not, see <http://www.gnu.org/licenses/>.
14
15# This package provides macros that wrap the intltool programs.
16#
17# An example of common usage is:
18#
19# For an ini file:
20#
21# intltool_merge_translations(
22# "foo.ini.in"
23# "${CMAKE_CURRENT_BINARY_DIR}/foo.ini"
24# ALL
25# UTF8
26# )
27#
28# Inside po/CMakeLists.txt:
29#
30# intltool_update_potfile(
31# ALL
32# GETTEXT_PACKAGE ${GETTEXT_PACKAGE}
33# )
34#
35# intltool_install_translations(
36# ALL
37# GETTEXT_PACKAGE ${GETTEXT_PACKAGE}
38# )
39
40find_package(Gettext REQUIRED)
41
42find_program(INTLTOOL_UPDATE_EXECUTABLE intltool-update)
43
44if(INTLTOOL_UPDATE_EXECUTABLE)
45 execute_process(
46 COMMAND ${INTLTOOL_UPDATE_EXECUTABLE} --version
47 OUTPUT_VARIABLE intltool_update_version
48 ERROR_QUIET
49 OUTPUT_STRIP_TRAILING_WHITESPACE)
50 if (intltool_update_version MATCHES "^intltool-update \\(.*\\) [0-9]")
51 string(
52 REGEX REPLACE "^intltool-update \\([^\\)]*\\) ([0-9\\.]+[^ \n]*).*" "\\1"
53 INTLTOOL_UPDATE_VERSION_STRING "${intltool_update_version}"
54 )
55 endif()
56 unset(intltool_update_version)
57endif()
58
59find_program(INTLTOOL_MERGE_EXECUTABLE intltool-merge)
60
61if(INTLTOOL_MERGE_EXECUTABLE)
62 execute_process(
63 COMMAND ${INTLTOOL_MERGE_EXECUTABLE} --version
64 OUTPUT_VARIABLE intltool_merge_version
65 ERROR_QUIET
66 OUTPUT_STRIP_TRAILING_WHITESPACE)
67 if (intltool_update_version MATCHES "^intltool-merge \\(.*\\) [0-9]")
68 string(
69 REGEX REPLACE "^intltool-merge \\([^\\)]*\\) ([0-9\\.]+[^ \n]*).*" "\\1"
70 INTLTOOL_MERGE_VERSION_STRING "${intltool_merge_version}"
71 )
72 endif()
73 unset(intltool_merge_version)
74endif()
75
76include(FindPackageHandleStandardArgs)
77
78find_package_handle_standard_args(
79 Intltool
80 REQUIRED_VARS
81 INTLTOOL_UPDATE_EXECUTABLE
82 INTLTOOL_MERGE_EXECUTABLE
83 VERSION_VAR
84 INTLTOOL_UPDATE_VERSION_STRING
85 HANDLE_COMPONENTS
86)
87
88function(APPEND_EACH LISTNAME GLUE OUTPUT)
89 set(_tmp_list "")
90 foreach(VAL ${${LISTNAME}})
91 list(APPEND _tmp_list "${GLUE}${VAL}")
92 endforeach(VAL ${${LISTNAME}})
93 set(${OUTPUT} "${_tmp_list}" PARENT_SCOPE)
94endfunction()
95
96function(INTLTOOL_UPDATE_POTFILE)
97 set(_options ALL)
98 set(_oneValueArgs GETTEXT_PACKAGE OUTPUT_FILE PO_DIRECTORY)
99
100 cmake_parse_arguments(_ARG "${_options}" "${_oneValueArgs}" "" ${ARGN})
101
102 set(_POT_FILE "${PROJECT}.pot")
103
104 set(_GETTEXT_PACKAGE "")
105 if(_ARG_GETTEXT_PACKAGE)
106 set(_POT_FILE "${_ARG_GETTEXT_PACKAGE}.pot")
107 set(_GETTEXT_PACKAGE --gettext-package="${_ARG_GETTEXT_PACKAGE}")
108 endif()
109
110 set(_OUTPUT_FILE "")
111 if(_ARG_OUTPUT_FILE)
112 set(_POT_FILE "${_ARG_OUTPUT_FILE}")
113 set(_OUTPUT_FILE --output-file="${_ARG_OUTPUT_FILE}")
114 endif()
115
116 set(_PO_DIRECTORY "${CMAKE_SOURCE_DIR}/po")
117 if(_ARG_PO_DIRECTORY)
118 set(_PO_DIRECTORY "${_ARG_PO_DIRECTORY}")
119 endif()
120
121 file(
122 GLOB_RECURSE _CODE_SOURCES
123 ${CMAKE_SOURCE_DIR}/*.cpp
124 ${CMAKE_SOURCE_DIR}/*.cc
125 ${CMAKE_SOURCE_DIR}/*.cxx
126 ${CMAKE_SOURCE_DIR}/*.vala
127 ${CMAKE_SOURCE_DIR}/*.c
128 ${CMAKE_SOURCE_DIR}/*.h
129 ${CMAKE_SOURCE_DIR}/*.ini.in
130 )
131
132 add_custom_command(
133 OUTPUT "${_POT_FILE}"
134 COMMAND ${INTLTOOL_UPDATE_EXECUTABLE} --pot ${_OUTPUT_FILE} ${_GETTEXT_PACKAGE}
135 DEPENDS
136 "${_PO_DIRECTORY}/POTFILES.in"
137 ${_CODE_SOURCES}
138 WORKING_DIRECTORY ${_PO_DIRECTORY}
139 )
140
141 _GETTEXT_GET_UNIQUE_TARGET_NAME(${_POT_FILE} _UNIQUE_TARGET_NAME)
142
143 if(_ARG_ALL)
144 add_custom_target(
145 ${_UNIQUE_TARGET_NAME}
146 ALL
147 DEPENDS
148 ${_POT_FILE}
149 )
150 else()
151 add_custom_target(
152 ${_UNIQUE_TARGET_NAME}
153 DEPENDS
154 ${_POT_FILE}
155 )
156 endif()
157endfunction()
158
159function(INTLTOOL_INSTALL_TRANSLATIONS)
160 set(_options ALL)
161 set(_oneValueArgs GETTEXT_PACKAGE POT_FILE)
162
163 cmake_parse_arguments(_ARG "${_options}" "${_oneValueArgs}" "" ${ARGN})
164
165 set(_POT_FILE "${PROJECT}.pot")
166
167 if(_ARG_GETTEXT_PACKAGE)
168 set(_POT_FILE "${_ARG_GETTEXT_PACKAGE}.pot")
169 endif()
170
171 if(_ARG_OUTPUT_FILE)
172 set(_POT_FILE "${_ARG_OUTPUT_FILE}")
173 endif()
174
175 file(
176 GLOB _PO_FILES
177 ${CMAKE_CURRENT_SOURCE_DIR}/*.po
178 )
179
180 get_filename_component(_ABS_POT_FILE ${_POT_FILE} ABSOLUTE)
181
182 foreach(_PO_FILE ${_PO_FILES})
183 add_custom_command(
184 OUTPUT
185 ${_PO_FILE}
186 COMMAND
187 ${GETTEXT_MSGMERGE_EXECUTABLE} --quiet --update --backup=none -s ${_PO_FILE} ${_ABS_POT_FILE}
188 DEPENDS
189 ${_ABS_POT_FILE}
190 )
191 endforeach()
192
193 if(_ARG_ALL)
194 gettext_create_translations(
195 ${_POT_FILE}
196 ALL
197 ${_PO_FILES}
198 )
199 else()
200 gettext_create_translations(
201 ${_POT_FILE}
202 ${_PO_FILES}
203 )
204 endif()
205endfunction()
206
207function(INTLTOOL_MERGE_TRANSLATIONS FILENAME OUTPUT_FILE)
208 set(_options ALL UTF8 PASS_THROUGH)
209 set(_oneValueArgs PO_DIRECTORY)
210
211 cmake_parse_arguments(_ARG "${_options}" "${_oneValueArgs}" "" ${ARGN})
212
213 get_filename_component(_ABS_FILENAME ${FILENAME} ABSOLUTE)
214
215 set(_PO_DIRECTORY "${CMAKE_SOURCE_DIR}/po")
216 if(_ARG_PO_DIRECTORY)
217 set(_PO_DIRECTORY "${_ARG_PO_DIRECTORY}")
218 endif()
219
220 set(_UTF8 "")
221 if(_ARG_UTF8)
222 set(_UTF8 "--utf8")
223 endif()
224
225 set(_PASS_THROUGH "")
226 if(_ARG_PASS_THROUGH)
227 set(_PASS_THROUGH "--pass-through")
228 endif()
229
230 file(
231 GLOB_RECURSE _PO_FILES
232 ${_PO_DIRECTORY}/*.po
233 )
234
235 add_custom_command(
236 OUTPUT
237 ${OUTPUT_FILE}
238 COMMAND
239 ${INTLTOOL_MERGE_EXECUTABLE} --desktop-style --quiet ${_UTF8} ${_PASS_THROUGH} ${_PO_DIRECTORY} ${FILENAME} ${OUTPUT_FILE}
240 DEPENDS
241 ${_ABS_FILENAME}
242 ${_PO_FILES}
243 WORKING_DIRECTORY
244 ${CMAKE_CURRENT_SOURCE_DIR}
245 )
246
247 get_filename_component(_OUTPUT_NAME ${OUTPUT_FILE} NAME)
248 _GETTEXT_GET_UNIQUE_TARGET_NAME(${_OUTPUT_NAME} _UNIQUE_TARGET_NAME)
249
250 if(_ARG_ALL)
251 add_custom_target(
252 ${_UNIQUE_TARGET_NAME}
253 ALL
254 DEPENDS
255 ${OUTPUT_FILE}
256 )
257 else()
258 add_custom_target(
259 ${_UNIQUE_TARGET_NAME}
260 DEPENDS
261 ${OUTPUT_FILE}
262 )
263 endif()
264endfunction()
265
0266
=== added directory 'data'
=== added file 'data/CMakeLists.txt'
--- data/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ data/CMakeLists.txt 2015-05-20 13:57:15 +0000
@@ -0,0 +1,12 @@
1
2# Install the scope images
3install(
4 FILES
5 "icon.png"
6 "logo.png"
7 "screenshot.png"
8 "feeds.json"
9 DESTINATION
10 "${SCOPE_INSTALL_DIR}"
11)
12
013
=== added file 'data/feeds.json'
--- data/feeds.json 1970-01-01 00:00:00 +0000
+++ data/feeds.json 2015-05-20 13:57:15 +0000
@@ -0,0 +1,46 @@
1[
2 {
3 "label": "All",
4 "id": "http://www.vox.com/rss/index.xml"
5 },
6 {
7 "label": "Front Page",
8 "id": "http://www.vox.com/rss/front-page/index.xml"
9 },
10 {
11 "label": "Business and Technology",
12 "id": "http://www.vox.com/rss/business_and_technology/index.xml"
13 },
14 {
15 "label": "Culture",
16 "id": "http://www.vox.com/rss/culture/index.xml"
17 },
18 {
19 "label": "Policy and Politics",
20 "id": "http://www.vox.com/rss/policy_and_politics/index.xml"
21 },
22 {
23 "label": "Life",
24 "id": "http://www.vox.com/rss/life/index.xml"
25 },
26 {
27 "label": "Videos",
28 "id": "http://www.vox.com/rss/videos/index.xml"
29 },
30 {
31 "label": "Maps",
32 "id": "http://www.vox.com/rss/maps/index.xml"
33 },
34 {
35 "label": "World and Defense",
36 "id": "http://www.vox.com/rss/world_and_defense/index.xml"
37 },
38 {
39 "label": "Justice and Law",
40 "id": "http://www.vox.com/rss/justice_and_law/index.xml"
41 },
42 {
43 "label": "Science of Everyday Life",
44 "id": "http://www.vox.com/rss/life-science/index.xml"
45 }
46]
047
=== added file 'data/icon.png'
1Binary files data/icon.png 1970-01-01 00:00:00 +0000 and data/icon.png 2015-05-20 13:57:15 +0000 differ48Binary files data/icon.png 1970-01-01 00:00:00 +0000 and data/icon.png 2015-05-20 13:57:15 +0000 differ
=== added file 'data/logo.png'
2Binary files data/logo.png 1970-01-01 00:00:00 +0000 and data/logo.png 2015-05-20 13:57:15 +0000 differ49Binary files data/logo.png 1970-01-01 00:00:00 +0000 and data/logo.png 2015-05-20 13:57:15 +0000 differ
=== added file 'data/rss.canonical_rss.ini.in'
--- data/rss.canonical_rss.ini.in 1970-01-01 00:00:00 +0000
+++ data/rss.canonical_rss.ini.in 2015-05-20 13:57:15 +0000
@@ -0,0 +1,11 @@
1[ScopeConfig]
2_DisplayName=Vox
3_Description=Vox
4Art=screenshot.png
5Author=Scott Sweeny
6Icon=icon.png
7
8[Appearance]
9PageHeader.Logo=logo.png
10PageHeader.Background=color:///#e9e7e8
11PageHeader.DividerColor=#ffeb00
012
=== added file 'data/screenshot.png'
1Binary files data/screenshot.png 1970-01-01 00:00:00 +0000 and data/screenshot.png 2015-05-20 13:57:15 +0000 differ13Binary files data/screenshot.png 1970-01-01 00:00:00 +0000 and data/screenshot.png 2015-05-20 13:57:15 +0000 differ
=== added directory 'include'
=== added directory 'include/api'
=== added file 'include/api/client.h'
--- include/api/client.h 1970-01-01 00:00:00 +0000
+++ include/api/client.h 2015-05-20 13:57:15 +0000
@@ -0,0 +1,84 @@
1/*
2 * Copyright 2015 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authors:
17 * Scott Sweeny
18 */
19
20#ifndef API_CLIENT_H_
21#define API_CLIENT_H_
22
23#include <atomic>
24#include <deque>
25#include <map>
26#include <string>
27#include <core/net/http/request.h>
28#include <core/net/uri.h>
29
30#include <QXmlStreamReader>
31
32namespace api {
33
34/**
35 * Provide a nice way to access the HTTP API.
36 *
37 * We don't want our scope's code to be mixed together with HTTP and JSON handling.
38 */
39class Client {
40public:
41
42 struct Item {
43 std::string title;
44 std::string published;
45 std::string author;
46 std::string art;
47 std::string uri;
48 std::string summary;
49 std::string content;
50 };
51
52 Client();
53
54 virtual ~Client() = default;
55
56 /**
57 * Get the feed content
58 */
59 virtual std::vector<Item> getItems(const std::string &url);
60
61 /**
62 * Cancel any pending queries (this method can be called from a different thread)
63 */
64 virtual void cancel();
65
66protected:
67 void get(const std::string &url, QXmlStreamReader &reader);
68 void parseItem(std::vector<Item>& results, QXmlStreamReader& xml);
69 /**
70 * Progress callback that allows the query to cancel pending HTTP requests.
71 */
72 core::net::http::Request::Progress::Next progress_report(
73 const core::net::http::Request::Progress& progress);
74
75 /**
76 * Thread-safe cancelled flag
77 */
78 std::atomic<bool> cancelled_;
79};
80
81}
82
83#endif // API_CLIENT_H_
84
085
=== added file 'include/api/config.h'
--- include/api/config.h 1970-01-01 00:00:00 +0000
+++ include/api/config.h 2015-05-20 13:57:15 +0000
@@ -0,0 +1,44 @@
1/*
2 * Copyright 2015 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authors:
17 * Scott Sweeny
18 */
19
20#ifndef API_CONFIG_H_
21#define API_CONFIG_H_
22
23#include <memory>
24#include <string>
25
26namespace api {
27
28struct Config {
29 typedef std::shared_ptr<Config> Ptr;
30
31 /* The XML element names of the fields we want */
32 std::string title = "title";
33 std::string subtitle = "pubDate";
34 std::string art = "enclosure";
35 std::string uri = "link";
36 std::string summary = "description";
37 std::string content = "content:encoded";
38 std::string item = "item";
39};
40
41}
42
43#endif /* API_CONFIG_H_ */
44
045
=== added directory 'include/scope'
=== added file 'include/scope/localization.h'
--- include/scope/localization.h 1970-01-01 00:00:00 +0000
+++ include/scope/localization.h 2015-05-20 13:57:15 +0000
@@ -0,0 +1,39 @@
1/*
2 * Copyright 2015 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef SCOPE_LOCALIZATION_H_
18#define SCOPE_LOCALIZATION_H_
19
20#include <libintl.h>
21#include <string>
22
23inline char * _(const char *__msgid) {
24 return dgettext(GETTEXT_PACKAGE, __msgid);
25}
26
27inline std::string _(const char *__msgid1, const char *__msgid2,
28 unsigned long int __n) {
29 char buffer [256];
30 if (snprintf ( buffer, 256, dngettext(GETTEXT_PACKAGE, __msgid1, __msgid2, __n), __n ) >= 0) {
31 return buffer;
32 } else {
33 return std::string();
34 }
35}
36
37#endif // SCOPE_LOCALIZATION_H_
38
39
040
=== added file 'include/scope/preview.h'
--- include/scope/preview.h 1970-01-01 00:00:00 +0000
+++ include/scope/preview.h 2015-05-20 13:57:15 +0000
@@ -0,0 +1,57 @@
1/*
2 * Copyright 2015 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authors:
17 * Scott Sweeny
18 */
19
20#ifndef SCOPE_PREVIEW_H_
21#define SCOPE_PREVIEW_H_
22
23#include <unity/scopes/PreviewQueryBase.h>
24
25namespace unity {
26namespace scopes {
27class Result;
28}
29}
30
31namespace scope {
32
33/**
34 * Represents an individual preview request.
35 *
36 * Each time a result is previewed in the UI a new Preview
37 * object is created.
38 */
39class Preview: public unity::scopes::PreviewQueryBase {
40public:
41 Preview(const unity::scopes::Result &result,
42 const unity::scopes::ActionMetadata &metadata);
43
44 ~Preview() = default;
45
46 void cancelled() override;
47
48 /**
49 * Populates the reply object with preview information.
50 */
51 void run(unity::scopes::PreviewReplyProxy const& reply) override;
52};
53
54}
55
56#endif // SCOPE_PREVIEW_H_
57
058
=== added file 'include/scope/query.h'
--- include/scope/query.h 1970-01-01 00:00:00 +0000
+++ include/scope/query.h 2015-05-20 13:57:15 +0000
@@ -0,0 +1,58 @@
1/*
2 * Copyright 2015 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authors:
17 * Scott Sweeny
18 */
19
20#ifndef SCOPE_QUERY_H_
21#define SCOPE_QUERY_H_
22
23#include <api/client.h>
24
25#include <unity/scopes/SearchQueryBase.h>
26#include <unity/scopes/ReplyProxyFwd.h>
27
28namespace scope {
29
30/**
31 * Represents an individual query.
32 *
33 * A new Query object will be constructed for each query. It is
34 * given query information, metadata about the search, and
35 * some scope-specific configuration.
36 */
37class Query: public unity::scopes::SearchQueryBase {
38public:
39 Query(const unity::scopes::CannedQuery &query,
40 const unity::scopes::SearchMetadata &metadata,
41 const std::string scope_directory);
42
43 ~Query() = default;
44
45 void cancelled() override;
46
47 void run(const unity::scopes::SearchReplyProxy &reply) override;
48
49private:
50 api::Client client_;
51 std::string scope_directory_;
52};
53
54}
55
56#endif // SCOPE_QUERY_H_
57
58
059
=== added file 'include/scope/scope.h'
--- include/scope/scope.h 1970-01-01 00:00:00 +0000
+++ include/scope/scope.h 2015-05-20 13:57:15 +0000
@@ -0,0 +1,70 @@
1/*
2 * Copyright 2015 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authors:
17 * Scott Sweeny
18 */
19
20#ifndef SCOPE_SCOPE_H_
21#define SCOPE_SCOPE_H_
22
23#include <api/config.h>
24
25#include <unity/scopes/ScopeBase.h>
26#include <unity/scopes/QueryBase.h>
27#include <unity/scopes/ReplyProxyFwd.h>
28#include <unity/scopes/QueryBase.h>
29#include <unity/scopes/PreviewQueryBase.h>
30
31namespace scope {
32
33/**
34 * Defines the lifecycle of scope plugin, and acts as a factory
35 * for Query and Preview objects.
36 *
37 * Note that the #preview and #search methods are each called on
38 * different threads, so some form of interlocking is required
39 * if shared data structures are used.
40 */
41class Scope: public unity::scopes::ScopeBase {
42public:
43 /**
44 * Called once at startup
45 */
46 void start(std::string const&) override;
47
48 /**
49 * Called at shutdown
50 */
51 void stop() override;
52
53 /**
54 * Called each time a new preview is requested
55 */
56 unity::scopes::PreviewQueryBase::UPtr preview(const unity::scopes::Result&,
57 const unity::scopes::ActionMetadata&) override;
58
59 /**
60 * Called each time a new query is requested
61 */
62 unity::scopes::SearchQueryBase::UPtr search(
63 unity::scopes::CannedQuery const& q,
64 unity::scopes::SearchMetadata const&) override;
65};
66
67}
68
69#endif // SCOPE_SCOPE_H_
70
071
=== added file 'manifest.json.in'
--- manifest.json.in 1970-01-01 00:00:00 +0000
+++ manifest.json.in 2015-05-20 13:57:15 +0000
@@ -0,0 +1,15 @@
1{
2 "architecture": "@CLICK_ARCH@",
3 "description": "A simple Unity scope that accesses the network",
4 "framework": "ubuntu-sdk-14.10",
5 "hooks": {
6 "rss": {
7 "apparmor": "rss.apparmor",
8 "scope": "rss"
9 }
10 },
11 "maintainer": "Scott Sweeny <scott.sweeny@canonical.com>",
12 "name": "rss.canonical",
13 "title": "rss",
14 "version": "0.1"
15}
016
=== added directory 'po'
=== added file 'po/CMakeLists.txt'
--- po/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ po/CMakeLists.txt 2015-05-20 13:57:15 +0000
@@ -0,0 +1,10 @@
1intltool_update_potfile(
2 ALL
3 GETTEXT_PACKAGE ${GETTEXT_PACKAGE}
4)
5
6intltool_install_translations(
7 ALL
8 GETTEXT_PACKAGE ${GETTEXT_PACKAGE}
9)
10
011
=== added file 'po/Makefile.in.in'
--- po/Makefile.in.in 1970-01-01 00:00:00 +0000
+++ po/Makefile.in.in 2015-05-20 13:57:15 +0000
@@ -0,0 +1,1 @@
1XGETTEXT_KEYWORDS=--c++ --keyword=_ --keyword=N_ --keyword=_:1,2
02
=== added file 'po/POTFILES.in'
--- po/POTFILES.in 1970-01-01 00:00:00 +0000
+++ po/POTFILES.in 2015-05-20 13:57:15 +0000
@@ -0,0 +1,12 @@
1[type: gettext/ini] data/rss.canonical_rss.ini.in
2include/api/config.h
3include/api/client.h
4include/scope/preview.h
5include/scope/localization.h
6include/scope/query.h
7include/scope/scope.h
8src/api/client.cpp
9src/scope/query.cpp
10src/scope/scope.cpp
11src/scope/preview.cpp
12
013
=== added file 'po/rss.pot'
--- po/rss.pot 1970-01-01 00:00:00 +0000
+++ po/rss.pot 2015-05-20 13:57:15 +0000
@@ -0,0 +1,26 @@
1# SOME DESCRIPTIVE TITLE.
2# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
3# This file is distributed under the same license as the PACKAGE package.
4# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
5#
6#, fuzzy
7msgid ""
8msgstr ""
9"Project-Id-Version: PACKAGE VERSION\n"
10"Report-Msgid-Bugs-To: \n"
11"POT-Creation-Date: 2015-05-20 09:29-0400\n"
12"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14"Language-Team: LANGUAGE <LL@li.org>\n"
15"Language: \n"
16"MIME-Version: 1.0\n"
17"Content-Type: text/plain; charset=CHARSET\n"
18"Content-Transfer-Encoding: 8bit\n"
19
20#: ../data/rss.canonical_rss.ini.in.h:1
21msgid "Vox"
22msgstr ""
23
24#: ../src/scope/query.cpp:214
25msgid "Open"
26msgstr ""
027
=== added file 'readme.txt'
--- readme.txt 1970-01-01 00:00:00 +0000
+++ readme.txt 2015-05-20 13:57:15 +0000
@@ -0,0 +1,26 @@
1Unity scope template
2
3Building
4--------
5
6To build this scope outside of QtCreator, please install phablet-tools and run click-buddy.
7
8Localization
9------------
10
11intltool is used to perform localization of the scope. Ensure whenever you add / rename files
12that contain localizable strings you update "po/POTFILES.in".
13
14When you want to add a new language to the translation catalogue:
15
16 * Copy the .pot file from the "po" directory and rename it to e.g. "zh_CH.po".
17 * Enter the language code in "Language:".
18 * Enter the "UTF-8" as the "Content-Type:".
19 * Enter the translations in the msgstr tags.
20
21For the new translation to show up, cmake needs to be re-run to enable the recusive search
22macro to delect the new translation. In QtCreator this can be done with the "Build->Run Cmake"
23menu entry.
24
25Remember! When you copy the .pot file, make sure you change the file extension to ".po".
26
027
=== added file 'rss.apparmor'
--- rss.apparmor 1970-01-01 00:00:00 +0000
+++ rss.apparmor 2015-05-20 13:57:15 +0000
@@ -0,0 +1,7 @@
1{
2 "template": "ubuntu-scope-network",
3 "policy_groups": [],
4 "policy_version": 1.2
5}
6
7
08
=== added directory 'src'
=== added file 'src/CMakeLists.txt'
--- src/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ src/CMakeLists.txt 2015-05-20 13:57:15 +0000
@@ -0,0 +1,97 @@
1
2# Put the ini file in the build directory next to the scope
3# .so file so test tools can find both easily.
4intltool_merge_translations(
5 "${CMAKE_SOURCE_DIR}/data/${SCOPE_NAME}.ini.in"
6 "${CMAKE_CURRENT_BINARY_DIR}/${SCOPE_NAME}.ini"
7 ALL
8 UTF8
9)
10
11# Install the scope ini file
12install(
13 FILES "${CMAKE_CURRENT_BINARY_DIR}/${SCOPE_NAME}.ini"
14 DESTINATION ${SCOPE_INSTALL_DIR}
15)
16
17configure_file(
18 "${CMAKE_SOURCE_DIR}/data/logo.png"
19 "${CMAKE_CURRENT_BINARY_DIR}/logo.png"
20 @ONLY
21 COPYONLY
22)
23
24configure_file(
25 "${CMAKE_SOURCE_DIR}/data/feeds.json"
26 "${CMAKE_CURRENT_BINARY_DIR}/feeds.json"
27 @ONLY
28 COPYONLY
29)
30
31configure_file(
32 "${CMAKE_SOURCE_DIR}/data/icon.png"
33 "${CMAKE_CURRENT_BINARY_DIR}/icon.png"
34 @ONLY
35 COPYONLY
36)
37
38# The sources to build the scope
39set(SCOPE_SOURCES
40 api/client.cpp
41 scope/preview.cpp
42 scope/query.cpp
43 scope/scope.cpp
44)
45
46# Find all the headers
47file(GLOB_RECURSE
48 SCOPE_HEADERS
49 "${CMAKE_SOURCE_DIR}/include/*.h"
50)
51
52# Build an object library for the scope code
53add_library(
54 scope-static OBJECT
55 ${SCOPE_SOURCES}
56 ${SCOPE_HEADERS}
57)
58
59# Ensure we export all the symbols
60set_target_properties(
61 scope-static
62 PROPERTIES
63 LINK_FLAGS "-Wl,--export-all-symbols"
64)
65
66# Build a shared library containing our scope code.
67# This will be the actual plugin that is loaded.
68add_library(
69 scope SHARED
70 $<TARGET_OBJECTS:scope-static>
71)
72
73# Link against the object library and our external library dependencies
74target_link_libraries(
75 scope
76 ${SCOPE_LDFLAGS}
77 ${Boost_LIBRARIES}
78)
79
80qt5_use_modules(
81 scope
82 Core
83)
84
85# Set the correct library output name to conform to the securiry policy
86set_target_properties(
87 scope
88 PROPERTIES
89 OUTPUT_NAME "${SCOPE_NAME}"
90)
91
92# Install the scope shared library
93install(
94 TARGETS scope
95 LIBRARY DESTINATION ${SCOPE_INSTALL_DIR}
96)
97
098
=== added directory 'src/api'
=== added file 'src/api/client.cpp'
--- src/api/client.cpp 1970-01-01 00:00:00 +0000
+++ src/api/client.cpp 2015-05-20 13:57:15 +0000
@@ -0,0 +1,271 @@
1/*
2 * Copyright 2015 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authors:
17 * Scott Sweeny
18 */
19
20#include <api/client.h>
21
22#include <core/net/error.h>
23#include <core/net/http/client.h>
24#include <core/net/http/content_type.h>
25#include <core/net/http/response.h>
26
27#include <QDebug>
28
29namespace http = core::net::http;
30namespace net = core::net;
31
32using namespace api;
33using namespace std;
34
35Client::Client() :
36 cancelled_(false) {
37}
38
39namespace {
40static string readText(QXmlStreamReader& xml)
41{
42 return xml.readElementText(QXmlStreamReader::IncludeChildElements).trimmed().toStdString();
43}
44
45static void getArtFromBody(Client::Item& item)
46{
47 if (item.art.empty()) {
48 qDebug() << "ART IS EMPTY";
49 // Use the first image in the summary if one exists
50 if (!(item.summary.empty()) && (item.summary.find("<img")!= string::npos)){
51 qDebug() << "FOUND IMG TAG IN SUMMARY";
52 QString summary = QString::fromStdString(item.summary);
53 QString aUrl = summary.right(summary.size() - summary.indexOf("<img"));
54 QString aSep = aUrl.mid(aUrl.indexOf("src=")+4,1);
55 aUrl = aUrl.right(aUrl.size()- aUrl.indexOf("src=")-5);
56 aUrl = aUrl.left(aUrl.indexOf(aSep));
57 if (!aUrl.contains(".gif"))
58 item.art = aUrl.toStdString();
59 qDebug()<< aUrl;
60 }
61 }
62
63 if (item.art.empty()) {
64 qDebug() << "ART IS EMPTY";
65 // Use the first image in the body if one exists
66 if (!(item.content.empty()) && (item.content.find("<img")!= string::npos)){
67 qDebug() << "FOUND IMG TAG IN BODY";
68 QString content = QString::fromStdString(item.content);
69 QString aUrl = content.right(content.size() - content.indexOf("<img"));
70 QString aSep = aUrl.mid(aUrl.indexOf("src=")+4,1);
71 aUrl = aUrl.right(aUrl.size()- aUrl.indexOf("src=")-5);
72 aUrl = aUrl.left(aUrl.indexOf(aSep));
73 if (!aUrl.contains(".gif"))
74 item.art = aUrl.toStdString();
75 qDebug()<< aUrl;
76 }
77 }
78}
79
80static void parseAuthor(Client::Item& item, QXmlStreamReader& xml)
81{
82 // In an ATOM feed, the author's name may be a subitem
83 if ((xml.name() == "author") || xml.qualifiedName() == "dc:creator") {
84 item.author = readText(xml);
85
86 if (item.author.empty()) { // there was no text so the name is below
87 xml.readNext();
88 if (xml.name() == "name") {
89 item.author = readText(xml);
90 }
91 }
92 }
93}
94
95static void parseLink(Client::Item& item, QXmlStreamReader& xml)
96{
97 // Atom feeds use a <link rel="alternate" href=.../> style
98 QXmlStreamAttributes attributes = xml.attributes();
99 if (attributes.hasAttribute("rel")) {
100 if ((attributes.value("rel") == "alternate") &&
101 attributes.hasAttribute("href")) {
102 item.uri = attributes.value("href").toString().toStdString();
103 }
104 } else {
105 // The URI should be in the text
106 item.uri = readText(xml);
107 }
108
109}
110
111static void parseArt(Client::Item& item, QXmlStreamReader& xml)
112{
113 if (xml.name() == "enclosure") {
114 QXmlStreamAttributes attributes = xml.attributes();
115 if (attributes.hasAttribute("url") &&
116 attributes.hasAttribute("type")) {
117 // We are only interested in image types
118 if (attributes.value("type").contains("image")) {
119 item.art = attributes.value("url").toString().toStdString();
120 }
121 }
122 } else if (xml.qualifiedName() == "media:thumbnail") {
123 QXmlStreamAttributes attributes = xml.attributes();
124 if (attributes.hasAttribute("url")) {
125 item.art = attributes.value("url").toString().toStdString();
126 }
127 }
128}
129
130static string sanitize(string contents)
131{
132 QString content = QString::fromStdString(contents); // easier from QString
133 content.remove(QRegExp("<[/]*(a|img)[^>]*>")) // strip links and image tags
134 .remove(QRegExp("<[/]*(br)[^>]*>")); // strip links and image tags
135 return content.toStdString();
136}
137
138}
139void Client::parseItem(vector<Client::Item>& results, QXmlStreamReader& xml)
140{
141 // Create a result object
142 Client::Item result;
143 while (!xml.atEnd() && !(xml.isEndElement() && (xml.name() == "item" || xml.name() == "entry")))
144 {
145 if (xml.isStartElement()) {
146 if (xml.name() == "title") {
147 result.title = xml.readElementText().toStdString();
148 qDebug() << "Title:" << QString::fromStdString(result.title);
149 } else if ((xml.name() == "pubDate") || (xml.name() == "published")) {
150 result.published = xml.readElementText().toStdString();
151 qDebug() << "Published:" << QString::fromStdString(result.published);
152 } else if (xml.name() == "link") {
153 parseLink(result, xml);
154 qDebug() << "Link:" << QString::fromStdString(result.uri);
155 } else if ((xml.name() == "enclosure") || (xml.qualifiedName() == "media:thumbnail")) {
156 parseArt(result, xml);
157 qDebug() << "Art:" << QString::fromStdString(result.art);
158 } else if ((xml.name() == "description") || (xml.name() == "summary")) {
159 qDebug() << "DESCRIPTION";
160 result.summary = readText(xml);
161 qDebug() << "Summary:" << QString::fromStdString(result.summary);
162 } else if ((xml.name() == "content") || (xml.qualifiedName() == "content:encoded")) {
163 result.content = readText(xml);
164 qDebug() << "Content:" << QString::fromStdString(result.content);
165 } else if ((xml.name() == "author") || (xml.qualifiedName() == "dc:creator")) {
166 parseAuthor(result, xml);
167 qDebug() << "Author:" << QString::fromStdString(result.author);
168 }
169 }
170 xml.readNext();
171 }
172
173 if (result.art.empty()) {
174 qDebug() << "GETTING ART FROM BODY";
175 getArtFromBody(result);
176 }
177
178 // Make sure we have both content and summary
179 if (result.content.empty() && !result.summary.empty()) {
180 result.content = result.summary;
181 }
182
183 if (result.summary.empty() && !result.content.empty()) {
184 result.summary = result.content;
185 }
186
187 // Strip image and link tags from content
188 result.summary = sanitize(result.summary);
189 result.content = sanitize(result.content);
190
191 // Add the item to our list of results
192 results.emplace_back(result);
193}
194
195void Client::get(const string &url, QXmlStreamReader &reader) {
196 qDebug() << "Client::get" << QString::fromStdString(url);
197 // Create a new HTTP client
198 auto client = http::make_client();
199
200 // Start building the request configuration
201 http::Request::Configuration configuration;
202
203 net::Uri uri = net::make_uri(url);
204 configuration.uri = client->uri_to_string(uri);
205
206 // Build a HTTP request object from our configuration
207 auto request = client->head(configuration);
208
209 try {
210 // Synchronously make the HTTP request
211 // We bind the cancellable callback to #progress_report
212 auto response = request->execute(
213 bind(&Client::progress_report, this, placeholders::_1));
214
215 // Check that we got a sensible HTTP status code
216 if (response.status != http::Status::ok) {
217 throw domain_error(response.body);
218 }
219 // Parse the Xml from the response
220 reader.addData(response.body.c_str());
221 } catch (net::Error &) {
222 }
223}
224
225vector<Client::Item> Client::getItems(const string& url) {
226 // This is the method that we will call from the Query class.
227 // It connects to an HTTP source and returns the results.
228 qDebug() << "getItems!!!";
229
230 // In this case we are going to retrieve XML data.
231 QXmlStreamReader root;
232 get(url, root);
233
234 vector<Item> results;
235
236
237 while (!root.atEnd() && !root.hasError()) {
238 Item result;
239 QXmlStreamReader::TokenType token = root.readNext();
240
241 /* If token is just StartDocument, we'll go to next.*/
242 if (token == QXmlStreamReader::StartDocument) {
243 continue;
244 }
245
246 /* If token is StartElement, we'll see if we can read it.*/
247 if (token == QXmlStreamReader::StartElement) {
248 if (root.name() == "item" || root.name() == "entry") {
249 parseItem(results, root);
250 }
251 }
252 }
253
254 if (root.hasError()) {
255 throw domain_error(root.errorString().toStdString());
256 }
257 return results;
258}
259
260http::Request::Progress::Next Client::progress_report(
261 const http::Request::Progress&) {
262
263 return cancelled_ ?
264 http::Request::Progress::Next::abort_operation :
265 http::Request::Progress::Next::continue_operation;
266}
267
268void Client::cancel() {
269 cancelled_ = true;
270}
271
0272
=== added directory 'src/scope'
=== added file 'src/scope/preview.cpp'
--- src/scope/preview.cpp 1970-01-01 00:00:00 +0000
+++ src/scope/preview.cpp 2015-05-20 13:57:15 +0000
@@ -0,0 +1,91 @@
1/*
2 * Copyright 2015 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authors:
17 * Scott Sweeny
18 */
19
20#include <scope/preview.h>
21
22#include <unity/scopes/ColumnLayout.h>
23#include <unity/scopes/PreviewWidget.h>
24#include <unity/scopes/PreviewReply.h>
25#include <unity/scopes/Result.h>
26#include <unity/scopes/VariantBuilder.h>
27
28#include <iostream>
29
30namespace sc = unity::scopes;
31
32using namespace std;
33using namespace scope;
34
35Preview::Preview(const sc::Result &result, const sc::ActionMetadata &metadata) :
36 sc::PreviewQueryBase(result, metadata) {
37}
38
39void Preview::cancelled() {
40}
41
42void Preview::run(sc::PreviewReplyProxy const& reply) {
43 // Support three different column layouts
44 sc::ColumnLayout layout1col(1), layout2col(2), layout3col(3);
45
46 // We define 3 different layouts, that will be used depending on the
47 // device. The shell (view) will decide which layout fits best.
48 // If, for instance, we are executing in a tablet probably the view will use
49 // 2 or more columns.
50 // Column layout definitions are optional.
51 // However, we recommend that scopes define layouts for the best visual appearance.
52
53 // Single column layout
54 layout1col.add_column( { "image", "header", "summary", "actions" });
55
56 // Two column layout
57 layout2col.add_column( { "image" });
58 layout2col.add_column( { "header", "summary", "actions" });
59
60 // Three cokumn layout
61 layout3col.add_column( { "image" });
62 layout3col.add_column( { "header", "summary", "actions" });
63 layout3col.add_column( { });
64
65 // Register the layouts we just created
66 reply->register_layout( { layout1col, layout2col, layout3col });
67
68 // Define the header section
69 sc::PreviewWidget header("header", "header");
70 // It has title and a subtitle properties
71 header.add_attribute_mapping("title", "title");
72 header.add_attribute_mapping("subtitle", "subtitle");
73
74 // Define the image section
75 sc::PreviewWidget image("image", "image");
76 // It has a single source property, mapped to the result's art property
77 image.add_attribute_mapping("source", "art");
78
79 // Define the summary section
80 sc::PreviewWidget description("summary", "text");
81 // It has a text property, mapped to the result's description property
82 description.add_attribute_mapping("text", "content");
83
84 // Define the action buttons
85 sc::PreviewWidget actions("actions", "actions");
86 actions.add_attribute_mapping("actions", "actions");
87
88 // Push each of the sections
89 reply->push( { image, header, description, actions });
90}
91
092
=== added file 'src/scope/query.cpp'
--- src/scope/query.cpp 1970-01-01 00:00:00 +0000
+++ src/scope/query.cpp 2015-05-20 13:57:15 +0000
@@ -0,0 +1,233 @@
1/*
2 * Copyright 2015 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authors:
17 * Scott Sweeny
18 */
19
20#include <boost/algorithm/string/trim.hpp>
21
22#include <scope/localization.h>
23#include <scope/query.h>
24
25#include <unity/scopes/Annotation.h>
26#include <unity/scopes/CategorisedResult.h>
27#include <unity/scopes/CategoryRenderer.h>
28#include <unity/scopes/Department.h>
29#include <unity/scopes/QueryBase.h>
30#include <unity/scopes/SearchReply.h>
31#include <unity/scopes/VariantBuilder.h>
32
33#include <iomanip>
34#include <sstream>
35
36#include <QDebug>
37#include <QFile>
38#include <QJsonArray>
39#include <QJsonDocument>
40#include <QJsonObject>
41
42namespace sc = unity::scopes;
43namespace alg = boost::algorithm;
44
45using namespace std;
46using namespace api;
47using namespace scope;
48
49
50std::string NEWS_LAYOUT = R"(
51{
52 "schema-version" : 1,
53 "template" : {
54 "category-layout" : "vertical-journal",
55 "card-layout": "horizontal",
56 "card-size": "small"
57 },
58 "components" : {
59 "title" : "title",
60 "subtitle":"published",
61 "summary":"summary",
62 "art":"art"
63 }
64}
65)";
66
67std::string ERROR_GRID = R"(
68{
69 "schema-version" : 1,
70 "template" : {
71 "category-layout" : "grid",
72 "card-layout": "horizontal",
73 "card-size": "small"
74 },
75 "components" : {
76 "title" : "title",
77 "mascot":"art",
78 "art" : {
79 "field": "art",
80 "aspect-ratio": 1.6,
81 "fill-mode": "fit"
82 }
83 }
84}
85)";
86
87QString getDepartments(QString filePath, sc::SearchReplyProxy const& reply) {
88 sc::DepartmentList depts;
89 QString rootDeptUrl;
90
91 // Read department names and URLs from the file
92 QFile departmentsFile(filePath);
93 if (!departmentsFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
94 qWarning() << "Departments file" << filePath << "not found";
95 return "";
96 }
97
98 QByteArray data = departmentsFile.readAll();
99 departmentsFile.close();
100
101 QJsonDocument doc = QJsonDocument::fromJson(data);
102 if (doc.isNull()){
103 qWarning() << "JSON parsing failed";
104 return "";
105 }
106 QJsonArray results = doc.array();
107
108 sc::CannedQuery myquery(SCOPE_NAME);
109 myquery.set_department_id("");
110 sc::Department::SPtr topDept;
111
112 auto value = results[0];
113 auto obj = value.toObject();
114 rootDeptUrl = obj["id"].toString();
115 topDept = move(sc::Department::create("",myquery,obj["label"].toString().toStdString()));
116
117 if (results.size() > 1) {
118 for (int i = 1; i < results.size(); ++i)
119 {
120 auto value = results[i];
121 auto obj = value.toObject();
122 sc::Department::SPtr aDept= move(sc::Department::create(obj["id"].toString().toStdString(),\
123 myquery,obj["label"].toString().toStdString()));
124 depts.insert(depts.end(),aDept);
125 }
126
127 topDept->set_subdepartments(depts);
128 reply->register_departments(topDept);
129 }
130 return rootDeptUrl;
131}
132
133Query::Query(const sc::CannedQuery &query, const sc::SearchMetadata &metadata, const string scope_directory) :
134 sc::SearchQueryBase(query, metadata),
135 client_(),
136 scope_directory_(scope_directory) {
137}
138
139void Query::cancelled() {
140 client_.cancel();
141}
142
143
144void Query::run(sc::SearchReplyProxy const& reply) {
145 try {
146 // Start by getting information about the query
147 const sc::CannedQuery &query(sc::SearchQueryBase::query());
148
149 // Trim the query string of whitespace
150 string query_string = alg::trim_copy(query.query_string());
151
152 // Get the departments
153 QString deptFile = QString::fromStdString(scope_directory_) + "/feeds.json";
154 string feedUrl = getDepartments(deptFile, reply).toStdString(); // feedUrl has the root URL
155
156 // If the current dept ID is empty use the root URL otherwise use
157 // the dept ID, which should be a department feed URL
158 if (!query.department_id().empty()) {
159 feedUrl = query.department_id();
160 }
161
162 if (feedUrl.empty()) {
163 // We can't proceed if we don't have a feed URL
164 qWarning() << "No feed URL found";
165 return;
166 }
167
168 vector<Client::Item> results = client_.getItems(feedUrl);
169
170 // Register a category for the forecast
171 auto news_cat = reply->register_category("news",
172 "", "", sc::CategoryRenderer(NEWS_LAYOUT));
173
174 // For each of the forecast days
175 for (const auto &item : results) {
176
177 // Filter by search term if we have one
178 if (!query_string.empty()) {
179 QString qry = QString::fromStdString(query_string);
180 QString title = QString::fromStdString(item.title);
181 QString summary = QString::fromStdString(item.summary);
182 QString content = QString::fromStdString(item.content);
183
184 if (!title.contains(qry, Qt::CaseInsensitive) &&
185 !summary.contains(qry, Qt::CaseInsensitive) &&
186 !content.contains(qry, Qt::CaseInsensitive)) {
187 continue;
188 }
189 }
190
191 // Create a result
192 sc::CategorisedResult res(news_cat);
193
194 // We must have a URI
195 res.set_uri(item.uri);
196 res.set_dnd_uri(item.uri);
197
198 // Set the rest of the attributes
199 res.set_title(item.title);
200 res.set_art(item.art);
201 res["published"] = sc::Variant(item.published);
202 res["author"] = sc::Variant(item.author);
203 res["summary"] = sc::Variant(item.summary);
204 res["content"] = sc::Variant(item.content);
205 res["emblem"] = sc::Variant(scope_directory_+"/images/emblem.png");
206
207 if (res.art().empty()) {
208 res.set_art(scope_directory_ + "/icon.png");
209 }
210
211 sc::VariantBuilder actions;
212 actions.add_tuple({
213 {"id", sc::Variant("open")},
214 {"label", sc::Variant(_("Open"))},
215 {"uri", sc::Variant(res.dnd_uri())}
216 });
217 res["actions"] = actions.end();
218
219 // Push the result
220 if (!reply->push(res)) {
221 // If we fail to push, it means the query has been cancelled.
222 // So don't continue;
223 return;
224 }
225 }
226
227 } catch (domain_error &e) {
228 // Handle exceptions being thrown by the client API
229 cerr << e.what() << endl;
230 reply->error(current_exception());
231 }
232}
233
0234
=== added file 'src/scope/scope.cpp'
--- src/scope/scope.cpp 1970-01-01 00:00:00 +0000
+++ src/scope/scope.cpp 2015-05-20 13:57:15 +0000
@@ -0,0 +1,77 @@
1/*
2 * Copyright 2015 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authors:
17 * Scott Sweeny
18 */
19
20#include <scope/localization.h>
21#include <scope/preview.h>
22#include <scope/query.h>
23#include <scope/scope.h>
24
25#include <iostream>
26#include <sstream>
27#include <fstream>
28
29namespace sc = unity::scopes;
30using namespace std;
31using namespace api;
32using namespace scope;
33
34void Scope::start(string const&) {
35
36 setlocale(LC_ALL, "");
37 string translation_directory = ScopeBase::scope_directory()
38 + "/../share/locale/";
39 bindtextdomain(GETTEXT_PACKAGE, translation_directory.c_str());
40}
41
42void Scope::stop() {
43}
44
45sc::SearchQueryBase::UPtr Scope::search(const sc::CannedQuery &query,
46 const sc::SearchMetadata &metadata) {
47 // Boilerplate construction of Query
48 return sc::SearchQueryBase::UPtr(new Query(query, metadata, scope_directory()));
49}
50
51sc::PreviewQueryBase::UPtr Scope::preview(sc::Result const& result,
52 sc::ActionMetadata const& metadata) {
53 // Boilerplate construction of Preview
54 return sc::PreviewQueryBase::UPtr(new Preview(result, metadata));
55}
56
57#define EXPORT __attribute__ ((visibility ("default")))
58
59// These functions define the entry points for the scope plugin
60extern "C" {
61
62EXPORT
63unity::scopes::ScopeBase*
64// cppcheck-suppress unusedFunction
65UNITY_SCOPE_CREATE_FUNCTION() {
66 return new Scope();
67}
68
69EXPORT
70void
71// cppcheck-suppress unusedFunction
72UNITY_SCOPE_DESTROY_FUNCTION(unity::scopes::ScopeBase* scope_base) {
73 delete scope_base;
74}
75
76}
77
078
=== added directory 'tests'
=== added file 'tests/CMakeLists.txt'
--- tests/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ tests/CMakeLists.txt 2015-05-20 13:57:15 +0000
@@ -0,0 +1,42 @@
1
2# Google Mock unfortunately has to be compiled from source
3include(FindGMock)
4
5# We need process-cpp to launch the python test server
6pkg_check_modules(
7 TEST
8 process-cpp
9 REQUIRED
10)
11
12# Include our test library headers
13include_directories(
14 ${GTEST_INCLUDE_DIRS}
15 ${GMOCK_INCLUDE_DIRS}
16 ${TEST_INCLUDE_DIRS}
17)
18
19# Where to find the scope ini file and .so
20add_definitions(
21# -DTEST_SCOPE_DIRECTORY="${CMAKE_BINARY_DIR}/src"
22)
23
24file(GLOB_RECURSE
25 TEST_FIXTURES
26 "server/*"
27 "unit/*"
28)
29
30# Make this file show up in QtCreator
31add_custom_target(hidden_test_fixtures ALL
32 SOURCES ${TEST_FIXTURES}
33)
34
35# Where to find the test server binary
36add_definitions(
37 -DFAKE_SERVER="${CMAKE_CURRENT_SOURCE_DIR}/server/server.py"
38)
39
40# Add the unit tests
41add_subdirectory(unit)
42
043
=== added directory 'tests/server'
=== added directory 'tests/server/bbc'
=== added directory 'tests/server/bbc/news'
=== added file 'tests/server/bbc/news/rss.xml'
--- tests/server/bbc/news/rss.xml 1970-01-01 00:00:00 +0000
+++ tests/server/bbc/news/rss.xml 2015-05-20 13:57:15 +0000
@@ -0,0 +1,40 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<?xml-stylesheet title="XSL_formatting" type="text/xsl" href="/shared/bsp/xsl/rss/nolsol.xsl"?>
3
4<rss xmlns:media="http://search.yahoo.com/mrss/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
5 <channel>
6 <title>BBC News - Home</title>
7 <link>http://www.bbc.co.uk/news/#sa-ns_mchannel=rss&amp;ns_source=PublicRSS20-sa</link>
8 <description>The latest stories from the Home section of the BBC News web site.</description>
9 <language>en-gb</language>
10 <lastBuildDate>Mon, 08 Dec 2014 15:15:32 GMT</lastBuildDate>
11 <copyright>Copyright: (C) British Broadcasting Corporation, see http://news.bbc.co.uk/2/hi/help/rss/4498287.stm for terms and conditions of reuse.</copyright>
12 <image>
13 <url>http://news.bbcimg.co.uk/nol/shared/img/bbc_news_120x60.gif</url>
14 <title>BBC News - Home</title>
15 <link>http://www.bbc.co.uk/news/#sa-ns_mchannel=rss&amp;ns_source=PublicRSS20-sa</link>
16 <width>120</width>
17 <height>60</height>
18 </image>
19 <ttl>15</ttl>
20 <atom:link href="http://feeds.bbci.co.uk/news/rss.xml" rel="self" type="application/rss+xml"/>
21 <item>
22 <title>Dewani cleared of honeymoon murder</title>
23 <description>The family of Anni Dewani believe they have been failed by the justice system after millionaire businessman Shrien Dewani is cleared of the honeymoon murder.</description>
24 <link>http://www.bbc.co.uk/news/uk-england-bristol-30375335#sa-ns_mchannel=rss&amp;ns_source=PublicRSS20-sa</link>
25 <guid isPermaLink="false">http://www.bbc.co.uk/news/uk-england-bristol-30375335</guid>
26 <pubDate>Mon, 08 Dec 2014 14:40:30 GMT</pubDate>
27 <media:thumbnail width="66" height="49" url="http://news.bbcimg.co.uk/media/images/79581000/jpg/_79581908_78423657.jpg"/>
28 <media:thumbnail width="144" height="81" url="http://news.bbcimg.co.uk/media/images/79581000/jpg/_79581909_78423657.jpg"/>
29 </item>
30 <item>
31 <title>'Pay benefits faster' to cut hunger</title>
32 <description>An income squeeze, benefit delays and high utility bills are blamed by a cross-party committee of MPs for a rise in hunger in the UK.</description>
33 <link>http://www.bbc.co.uk/news/education-30346060#sa-ns_mchannel=rss&amp;ns_source=PublicRSS20-sa</link>
34 <guid isPermaLink="false">http://www.bbc.co.uk/news/education-30346060</guid>
35 <pubDate>Mon, 08 Dec 2014 10:56:04 GMT</pubDate>
36 <media:thumbnail width="66" height="49" url="http://news.bbcimg.co.uk/media/images/79569000/jpg/_79569923_79569916.jpg"/>
37 <media:thumbnail width="144" height="81" url="http://news.bbcimg.co.uk/media/images/79569000/jpg/_79569924_79569916.jpg"/>
38 </item>
39 </channel>
40</rss>
041
=== added directory 'tests/server/cnet'
=== added directory 'tests/server/cnet/rss'
=== added directory 'tests/server/cnet/rss/all'
=== added file 'tests/server/cnet/rss/all/index.xml'
--- tests/server/cnet/rss/all/index.xml 1970-01-01 00:00:00 +0000
+++ tests/server/cnet/rss/all/index.xml 2015-05-20 13:57:15 +0000
@@ -0,0 +1,2 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<rss xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" version="2.0"><channel><title>CNET</title><link>http://www.cnet.com/#ftag=CADf328eec</link><description>The latest tech news, product reviews, videos, and how tos from CNET.</description><language>en</language><pubDate>Thu, 22 Jan 2015 14:59:05 GMT</pubDate><lastBuildDate>Thu, 22 Jan 2015 14:59:05 GMT</lastBuildDate><ttl>2</ttl><image><title>CNET</title><url>http://i.i.cbsi.com/cnwk.1d/i/ne/gr/prtnr/CNET_Logo_150.gif</url><link>http://www.cnet.com/#ftag=CADf328eec</link></image><item><title>Cook with gas like a pro on the hardy Decor Renaissance range</title><link>http://www.cnet.com/videos/cook-with-gas-like-a-pro-on-the-hardy-decor-renaissance-range/#ftag=CADf328eec</link><description>Dacor's new gas grilling monster is built to last and cook with lots of control.&lt;img width='1' height='1' src='http://cnet.com.feedsportal.com/c/34938/f/645450/s/42987c70/sc/36/mf.gif' border='0'/&gt;&lt;br clear='all'/&gt;&lt;br/&gt;&lt;br/&gt;&lt;a href="http://da.feedsportal.com/r/218610936754/u/57/f/645450/c/34938/s/42987c70/sc/36/rc/1/rc.htm" rel="nofollow"&gt;&lt;img src="http://da.feedsportal.com/r/218610936754/u/57/f/645450/c/34938/s/42987c70/sc/36/rc/1/rc.img" border="0"/&gt;&lt;/a&gt;&lt;br/&gt;&lt;a href="http://da.feedsportal.com/r/218610936754/u/57/f/645450/c/34938/s/42987c70/sc/36/rc/2/rc.htm" rel="nofollow"&gt;&lt;img src="http://da.feedsportal.com/r/218610936754/u/57/f/645450/c/34938/s/42987c70/sc/36/rc/2/rc.img" border="0"/&gt;&lt;/a&gt;&lt;br/&gt;&lt;a href="http://da.feedsportal.com/r/218610936754/u/57/f/645450/c/34938/s/42987c70/sc/36/rc/3/rc.htm" rel="nofollow"&gt;&lt;img src="http://da.feedsportal.com/r/218610936754/u/57/f/645450/c/34938/s/42987c70/sc/36/rc/3/rc.img" border="0"/&gt;&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;&lt;a href="http://da.feedsportal.com/r/218610936754/u/57/f/645450/c/34938/s/42987c70/sc/36/a2.htm"&gt;&lt;img src="http://da.feedsportal.com/r/218610936754/u/57/f/645450/c/34938/s/42987c70/sc/36/a2.img" border="0"/&gt;&lt;/a&gt;&lt;img width="1" height="1" src="http://pi.feedsportal.com/r/218610936754/u/57/f/645450/c/34938/s/42987c70/sc/36/a2t.img" border="0"/&gt;</description><pubDate>Thu, 22 Jan 2015 14:52:46 GMT</pubDate><guid>http://www.cnet.com/videos/cook-with-gas-like-a-pro-on-the-hardy-decor-renaissance-range/#ftag=CADf328eec</guid><dc:creator>Brian Bennett</dc:creator><media:thumbnail url="http://cnet3.cbsistatic.com/hub/i/r/2015/01/22/cf096def-ba6c-4fed-a624-5789eaa42cc1/thumbnail/300x230/84411a75f4fa59904efffe0cb1e9b371/fldacorrenaissanceprostylegasrange0.jpg" /></item><item><title>Dropbox app arrives on Windows tablets, phones</title><link>http://www.cnet.com/news/dropbox-official-app-arrives-on-windows-tablets-phones/#ftag=CADf328eec</link><description>Dropbox, Microsoft hope to win over more customers with improved work flow and compatibilty.&lt;img width='1' height='1' src='http://cnet.com.feedsportal.com/c/34938/f/645450/s/42987c74/sc/21/mf.gif' border='0'/&gt;&lt;br clear='all'/&gt;&lt;br/&gt;&lt;br/&gt;&lt;a href="http://da.feedsportal.com/r/218610936753/u/57/f/645450/c/34938/s/42987c74/sc/21/rc/1/rc.htm" rel="nofollow"&gt;&lt;img src="http://da.feedsportal.com/r/218610936753/u/57/f/645450/c/34938/s/42987c74/sc/21/rc/1/rc.img" border="0"/&gt;&lt;/a&gt;&lt;br/&gt;&lt;a href="http://da.feedsportal.com/r/218610936753/u/57/f/645450/c/34938/s/42987c74/sc/21/rc/2/rc.htm" rel="nofollow"&gt;&lt;img src="http://da.feedsportal.com/r/218610936753/u/57/f/645450/c/34938/s/42987c74/sc/21/rc/2/rc.img" border="0"/&gt;&lt;/a&gt;&lt;br/&gt;&lt;a href="http://da.feedsportal.com/r/218610936753/u/57/f/645450/c/34938/s/42987c74/sc/21/rc/3/rc.htm" rel="nofollow"&gt;&lt;img src="http://da.feedsportal.com/r/218610936753/u/57/f/645450/c/34938/s/42987c74/sc/21/rc/3/rc.img" border="0"/&gt;&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;&lt;a href="http://da.feedsportal.com/r/218610936753/u/57/f/645450/c/34938/s/42987c74/sc/21/a2.htm"&gt;&lt;img src="http://da.feedsportal.com/r/218610936753/u/57/f/645450/c/34938/s/42987c74/sc/21/a2.img" border="0"/&gt;&lt;/a&gt;&lt;img width="1" height="1" src="http://pi.feedsportal.com/r/218610936753/u/57/f/645450/c/34938/s/42987c74/sc/21/a2t.img" border="0"/&gt;</description><pubDate>Thu, 22 Jan 2015 14:45:36 GMT</pubDate><guid>http://www.cnet.com/news/dropbox-official-app-arrives-on-windows-tablets-phones/#ftag=CADf328eec</guid><dc:creator>Lance Whitney</dc:creator><media:thumbnail url="http://cnet3.cbsistatic.com/hub/i/r/2015/01/22/8ea8815f-4595-4184-a65f-6a494ea16e00/thumbnail/300x230/21ab57c0ba05d8ceb5dcf00a468e63e8/dropbox-windows-app.jpg" /></item></channel></rss>
03
=== added directory 'tests/server/elpais'
=== added file 'tests/server/elpais/portada.xml'
--- tests/server/elpais/portada.xml 1970-01-01 00:00:00 +0000
+++ tests/server/elpais/portada.xml 2015-05-20 13:57:15 +0000
@@ -0,0 +1,73 @@
1<?xml version="1.0" encoding="utf-8"?>
2<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/">
3<channel>
4 <title><![CDATA[Portada de EL PAÍS]]></title>
5 <link><![CDATA[http://elpais.com/rss/elpais/portada.xml]]></link>
6 <description><![CDATA[Portada de EL PAÍS]]></description>
7 <lastBuildDate>Thu, 22 Jan 2015 16:48:19 +0100</lastBuildDate>
8 <pubDate>Thu, 22 Jan 2015 16:48:19 +0100</pubDate>
9 <language>es</language>
10 <copyright><![CDATA[Copyright 2015, Ediciones EL PAÍS]]></copyright>
11 <ttl>5</ttl>
12 <image>
13 <url>http://ep00.epimg.net/iconos/v1.x/v1.0/logos/cabecera_portada.png</url>
14 <title>Logotipo de EL PAÍS</title>
15 <link>http://elpais.com/</link>
16 </image>
17 <item>
18 <title><![CDATA[Los mercados celebran el plan de compra de activos del BCE]]></title>
19 <link><![CDATA[http://elpais.com/economia/2015/01/22/actualidad/1421918178_469436.html]]></link>
20 <guid isPermaLink="true"><![CDATA[http://elpais.com/economia/2015/01/22/actualidad/1421918178_469436.html]]></guid>
21 <dc:creator><![CDATA[El País]]></dc:creator>
22 <description><![CDATA[Las Bolsas europeas suben tras los primeros detalles del programa de estímulo. La prima española baja de 100 puntos]]></description>
23 <pubDate><![CDATA[Thu, 22 Jan 2015 15:41:53 +0100]]></pubDate>
24 <category><![CDATA[Mario Draghi]]></category>
25 <category><![CDATA[BCE]]></category>
26 <category><![CDATA[Política financiera]]></category>
27 <category><![CDATA[Bolsa]]></category>
28 <category><![CDATA[Política económica]]></category>
29 <category><![CDATA[UE]]></category>
30 <category><![CDATA[Bancos]]></category>
31 <category><![CDATA[Mercados financieros]]></category>
32 <category><![CDATA[Europa]]></category>
33 <category><![CDATA[Banca]]></category>
34 <category><![CDATA[Economía]]></category>
35 <category><![CDATA[Finanzas]]></category>
36 <content:encoded><![CDATA[<p>Las Bolsas han recibido en verde el anuncio del <a href="http://economia.elpais.com/economia/2015/01/22/actualidad/1421930158_392049.html">plan de estímulo a la economía europea del Banco Central Europeo</a> (BCE). Pero pese al optimismo, los mercados tampoco han celebrado una fiesta: el <a href="http://resultados.elpais.com/mercados/indices/ibex_35/582/">Ibex 35</a> ha registrado alzas de menos del 1% mientras la rueda de prensa del presidente de Mario Draghi todavía seguía en marcha. Aunque sin excesos —<a href="http://economia.elpais.com/economia/2015/01/17/actualidad/1421529316_697978.html">el anuncio de Draghi llevaba semanas avanzándose</a>—, todas las plazas europeas se han teñido de verde.</p>
37<p>Los inversores llevaban meses esperando que el presidente Mario Draghi se decidiera a poner en marcha las medidas de política monetaria más agresivas. Desde principios de diciembre el día de hoy estaba marcado en el calendario como la jornada en la que todo indicaba que se anunciaría el programa. La expectación ha hecho que las Bolsas se apunten toda la semana subidas y que los bonos soberanos marquen cotas mínimas. Los inversores, advertían los analistas, estaban ya descontando el plan de Draghi, y de ahí que este jueves el salto de la Bolsa sea más bien tímido.</p>
38<p>El Ibex 35, el selectivo de la Bolsa española, ha titubeado, con subidas de entre el 0,8% y el 1,8%. Antes de la rueda de prensa de Draghi, estaba cerca de los 10.400 puntos. Con los primeros detalles del plan, que supondrá la compra de 60.000 millones de euros en activos cada mes, subía a 10.524 puntos. Y ya terminados los anuncios, cerca de las cuatro de la tarde, rondaba los 10.500 puntos, el 1,6% más. La banca y las empresas energéticas eran las que más tiraban del selectivo.</p>
39<p>La reacción del selectivo español ha sido de las más efusivas. Entre las grandes plazas, solo Milán celebraba con más entusiasmo los estímulos, con una subida cercana al 1,9% a media tarde. París subía el 1%, la Bolsa alemana medio punto y el índice combinado europeo Euro Stoxx más del 1%.</p>
40<p>La prima de riesgo española, que es el diferencial de interés que los inversores exigen en los bonos a 10 años españoles respecto de los alemanes, por la mañana ha bajado de los 100 puntos, y así se ha mantenido tras la rueda de prensa del BCE.</p>]]></content:encoded>
41 <enclosure url="http://ep00.epimg.net/economia/imagenes/2015/01/22/actualidad/1421918178_469436_1421919363_miniatura_normal.jpg" length="7780" type="image/jpeg" />
42 <enclosure url="http://ep00.epimg.net/economia/imagenes/2015/01/22/actualidad/1421918178_469436_1421919363_noticia_normal.jpg" length="47941" type="image/jpeg" />
43 <comments><![CDATA[http://eskup.elpais.com/C1421918177-a42f07be2996d7f8f79fac06f3ba4a3a]]></comments>
44 </item>
45 <item>
46 <title><![CDATA[La presidenta afirma que la muerte de Nisman “no fue suicidio”]]></title>
47 <link><![CDATA[http://elpais.com/internacional/2015/01/22/actualidad/1421925039_624424.html]]></link>
48 <guid isPermaLink="true"><![CDATA[http://elpais.com/internacional/2015/01/22/actualidad/1421925039_624424.html]]></guid>
49 <dc:creator><![CDATA[Francisco Peregil]]></dc:creator>
50 <description><![CDATA["La verdadera operación contra el Gobierno era la muerte del fiscal después de acusar a la presidenta", escribe Fernández]]></description>
51 <pubDate><![CDATA[Thu, 22 Jan 2015 16:47:52 +0100]]></pubDate>
52 <category><![CDATA[Caso AMIA]]></category>
53 <category><![CDATA[Alberto Nisman]]></category>
54 <category><![CDATA[Cristina Fernández de Kirchner]]></category>
55 <category><![CDATA[Investigación judicial]]></category>
56 <category><![CDATA[Casos judiciales]]></category>
57 <category><![CDATA[Atentados terroristas]]></category>
58 <category><![CDATA[Terrorismo]]></category>
59 <category><![CDATA[Proceso judicial]]></category>
60 <category><![CDATA[Justicia]]></category>
61 <content:encoded><![CDATA[<p>La presidenta de Argentina, Cristina Fernández, ha vuelto a escribir en <a href="https://es-es.facebook.com/CFKArgentina">Facebook</a> sobre la muerte del fiscal <a href="http://internacional.elpais.com/tag/natalio_alberto_nisman/a/">Alberto Nisman</a>, el hombre que la denunció por encubrimiento de terroristas cuatro días antes de fallecer con una bala incrustada en la cabeza. En un extenso mensaje de 2.900 palabras, <a href="http://ep00.epimg.net/descargables/2015/01/22/ee83afe3302baa81171063688a9f4d57.pdf">Fernández asegura que no cree que la muerte de Nisman se trate de un suicidio</a>. Y sostiene que "una rápida lectura" a la denuncia íntegra del fiscal no hace más que confirmar sus "peores sospechas". Es decir, que el informe de Nisman no aporta nada nuevo y que le "plantaron" pistas falsas y que Nisman fue utilizado dentro de una operación contra el Gobierno.</p>
62<p> Sin embargo, la denuncia del fiscal y su contenido ha pasado a segundo plano. Lo que se discute hoy por hoy son las circunstancias de la muerte de Nisman y la actuación del Gobierno respecto a ella. Cristina Fernández ya fue criticada por guardar silencio durante cinco días desde que el fiscal planteó el miércoles de la semana pasada una denuncia de una gravedad inusitada. Cuando Fernández eligió ofrecer una primera explicación lo hizo a través de Facebook el mismo día de su muerte. La oposición criticó que eligiera las redes sociales cuando la presidenta acostumbra a transmitir muchos de sus mensajes por "cadena nacional", es decir, mediante la difusión obligatoria en todos los canales de radio y televisión.</p>
63<p>En aquella primera carta por Facebook, Fernández habló de suicidio: "La muerte de una persona siempre causa dolor y pérdida entre sus seres queridos, y consternación en el resto. El suicidio provoca, además, en todos los casos, primero: estupor, y después: interrogantes. ¿Qué fue lo que llevó a una persona a tomar la terrible decisión de quitarse la vida?". A renglón seguido empleó los signos de interrogación: "En el caso del ¿suicidio? Del Fiscal a cargo de la causa AMIA (...) Pero en este segundo mensaje, apenas tres días después del primero, Fernández asegura ya estar convencida de que no se trató de un suicidio. El texto lo titula: "Los espías que no eran espías. Los interrogantes que se convierten en certeza. El suicidio (que estoy convencida) no fue suicidio".</p>
64<p>La muerte de Nisman parece haber dejado al Gobierno sin capacidad de reacción, sin iniciativa, al rebufo de los acontecimientos. La idea de que la presidenta Fernández convoque una conferencia de prensa es casi inconcebible. Pero su insistencia en mantenerse detrás del muro de Facebook ha soliviantado a la oposición. "Es incomprensible que la presidenta se siga comunicando por las redes", señaló el senador de la Unión Cívica Radical y precandidato a la presidencia, Ernesto Sanz.</p>
65<p>El mensaje de Fernández ha dado la señal al resto del Ejecutivo para cambiar de opinión. Uno de los primeros en hacerlo es Sergio Berni, el secretario de Seguridad, quien llegó a la casa de Nisman antes del juez y la fiscal. Berni fue la primera autoridad en señalar que todo apuntaba a un suicidio. Lo hizo horas antes de que se conocieran los primeros informes periciales. Sin embargo, después de conocerse el mensaje de la presidenta ha corregido sus palabras basándose en las declaraciones del cerrajero que abrió la puerta de servicio: "Cuando dice el cerrajero que la puerta estaba abierta, quiere decir que no estaba puesta con dos vueltas de llaves. Alguien puede haber salido por esa puerta". Y declaró: "la teoría del suicidio está cada vez más lejos".</p>
66<p>Respecto al contenido de la denuncia presentada por Nisman y publicada de forma íntegra en Internet, Fernández sostiene que no aporta nada nuevo. Y añade que a Nisman le "plantaron" información falsa en su informe."La acusación de Nisman no sólo se derrumba, sino que constituye un verdadero escándalo político y jurídico", asegura. Y precisa: "La denuncia del fiscal Nisman nunca fue en sí misma la verdadera operación contra el Gobierno. Se derrumbaba a poco de andar. Nisman no lo sabía y probablemente no lo supo nunca. La verdadera operación contra el Gobierno era la muerte del Fiscal después de acusar a la Presidenta, a su Canciller y al Secretario General de La Cámpora de ser encubridores de los iraníes acusados por <a href="http://www.google.es/url?sa=t&rct=j&q=&esrc=s&source=web&cd=5&cad=rja&uact=8&ved=0CD8QFjAE&url=http%3A%2F%2Felpais.com%2Ftag%2Fcaso_amia%2Fa%2F&ei=Qd7AVJ_KH4T_UJTAgcgD&usg=AFQjCNEtg-VXnV7cN6RzzUUWngZruUJ_ZA&bvm=bv.83829542,d.d24">el atentado de la AMIA".</a> Más adelante remacha: "Lo usaron vivo y después lo necesitaban muerto. Así de triste y terrible".</p>]]></content:encoded>
67 <enclosure url="http://ep00.epimg.net/internacional/imagenes/2015/01/22/actualidad/1421925039_624424_1421926785_miniatura_normal.jpg" length="4801" type="image/jpeg" />
68 <enclosure url="http://ep00.epimg.net/internacional/imagenes/2015/01/22/actualidad/1421925039_624424_1421926785_noticia_normal.jpg" length="22843" type="image/jpeg" />
69 <enclosure url="http://ep00.epimg.net/internacional/imagenes/2015/01/22/actualidad/1421925039_624424_1421926785_noticia_grande.jpg" length="61907" type="image/jpeg" />
70 <comments><![CDATA[http://eskup.elpais.com/C1421925039-804361179de943a9a7c88eebc78bcc35]]></comments>
71 </item>
72</channel>
73</rss>
074
=== added directory 'tests/server/euronews'
=== added directory 'tests/server/euronews/_partners'
=== added directory 'tests/server/euronews/_partners/ubuntu'
=== added file 'tests/server/euronews/_partners/ubuntu/news.xml'
--- tests/server/euronews/_partners/ubuntu/news.xml 1970-01-01 00:00:00 +0000
+++ tests/server/euronews/_partners/ubuntu/news.xml 2015-05-20 13:57:15 +0000
@@ -0,0 +1,2 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>euronews</title><link>http://www.euronews.com</link><description>The leading European News TV-channel. All the International news in 14.</description><language>en</language><pubDate>Wed, 21 Jan 2015 21:55:01 GMT</pubDate><lastBuildDate>Wed, 21 Jan 2015 21:55:01 GMT</lastBuildDate><ttl>2</ttl><image><link>http://www.euronews.net/</link><url>http://www.euronews.net/media/rss/logo-rss.png</url><title>euronews</title></image><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/euronews/en/home" /><feedburner:info uri="euronews/en/home" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item><title>US and Cuba differ on migration policy on first day of talks</title><link>http://feedproxy.google.com/~r/euronews/en/home/~3/jxq__KwrJ0E/story01.htm</link><description>Migration has proved a divisive issue on the first day of historic talks in Havana between senior Cuban and US officials - the first since both…&lt;img width='1' height='1' src='http://Euronews.net.feedsportal.com/c/32800/f/536666/s/4291afc7/sc/11/mf.gif' border='0'/&gt;&lt;br clear='all'/&gt;&lt;br/&gt;&lt;br/&gt;&lt;a href="http://da.feedsportal.com/r/218610861473/u/49/f/536666/c/32800/s/4291afc7/sc/11/rc/1/rc.htm" rel="nofollow"&gt;&lt;img src="http://da.feedsportal.com/r/218610861473/u/49/f/536666/c/32800/s/4291afc7/sc/11/rc/1/rc.img" border="0"/&gt;&lt;/a&gt;&lt;br/&gt;&lt;a href="http://da.feedsportal.com/r/218610861473/u/49/f/536666/c/32800/s/4291afc7/sc/11/rc/2/rc.htm" rel="nofollow"&gt;&lt;img src="http://da.feedsportal.com/r/218610861473/u/49/f/536666/c/32800/s/4291afc7/sc/11/rc/2/rc.img" border="0"/&gt;&lt;/a&gt;&lt;br/&gt;&lt;a href="http://da.feedsportal.com/r/218610861473/u/49/f/536666/c/32800/s/4291afc7/sc/11/rc/3/rc.htm" rel="nofollow"&gt;&lt;img src="http://da.feedsportal.com/r/218610861473/u/49/f/536666/c/32800/s/4291afc7/sc/11/rc/3/rc.img" border="0"/&gt;&lt;/a&gt;&lt;img src="//feeds.feedburner.com/~r/euronews/en/home/~4/jxq__KwrJ0E" height="1" width="1" alt=""/&gt;</description><pubDate>Wed, 21 Jan 2015 21:38:01 GMT</pubDate><guid isPermaLink="false">http://Euronews.net.feedsportal.com/c/32800/f/536666/s/4291afc7/sc/11/l/0L0Seuronews0N0C20A150C0A10C210Cus0Eand0Ecuba0Ediffer0Eon0Emigration0Epolicy0Eon0Efirst0Eday0Eof0Etalks0C/story01.htm</guid><feedburner:origLink>http://Euronews.net.feedsportal.com/c/32800/f/536666/s/4291afc7/sc/11/l/0L0Seuronews0N0C20A150C0A10C210Cus0Eand0Ecuba0Ediffer0Eon0Emigration0Epolicy0Eon0Efirst0Eday0Eof0Etalks0C/story01.htm</feedburner:origLink></item><item><title>PEGIDA leader quits amid 'Hitler' row</title><link>http://feedproxy.google.com/~r/euronews/en/home/~3/9_aOJCAU-lw/story01.htm</link><description>The leader of the anti-Islamisation PEGIDA party in Germany has quit amid a row over photo where he posed as Hitler and comments about immigrants on…&lt;img width='1' height='1' src='http://Euronews.net.feedsportal.com/c/32800/f/536666/s/4291afca/sc/3/mf.gif' border='0'/&gt;&lt;br clear='all'/&gt;&lt;br/&gt;&lt;br/&gt;&lt;a href="http://da.feedsportal.com/r/218610861472/u/49/f/536666/c/32800/s/4291afca/sc/3/rc/1/rc.htm" rel="nofollow"&gt;&lt;img src="http://da.feedsportal.com/r/218610861472/u/49/f/536666/c/32800/s/4291afca/sc/3/rc/1/rc.img" border="0"/&gt;&lt;/a&gt;&lt;br/&gt;&lt;a href="http://da.feedsportal.com/r/218610861472/u/49/f/536666/c/32800/s/4291afca/sc/3/rc/2/rc.htm" rel="nofollow"&gt;&lt;img src="http://da.feedsportal.com/r/218610861472/u/49/f/536666/c/32800/s/4291afca/sc/3/rc/2/rc.img" border="0"/&gt;&lt;/a&gt;&lt;br/&gt;&lt;a href="http://da.feedsportal.com/r/218610861472/u/49/f/536666/c/32800/s/4291afca/sc/3/rc/3/rc.htm" rel="nofollow"&gt;&lt;img src="http://da.feedsportal.com/r/218610861472/u/49/f/536666/c/32800/s/4291afca/sc/3/rc/3/rc.img" border="0"/&gt;&lt;/a&gt;&lt;img src="//feeds.feedburner.com/~r/euronews/en/home/~4/9_aOJCAU-lw" height="1" width="1" alt=""/&gt;</description><pubDate>Wed, 21 Jan 2015 21:34:03 GMT</pubDate><guid isPermaLink="false">http://Euronews.net.feedsportal.com/c/32800/f/536666/s/4291afca/sc/3/l/0L0Seuronews0N0C20A150C0A10C210Cpegida0Eleader0Equits0Eamid0Ehitler0Erow0C/story01.htm</guid><feedburner:origLink>http://Euronews.net.feedsportal.com/c/32800/f/536666/s/4291afca/sc/3/l/0L0Seuronews0N0C20A150C0A10C210Cpegida0Eleader0Equits0Eamid0Ehitler0Erow0C/story01.htm</feedburner:origLink></item></channel></rss>
03
=== added file 'tests/server/server.py'
--- tests/server/server.py 1970-01-01 00:00:00 +0000
+++ tests/server/server.py 2015-05-20 13:57:15 +0000
@@ -0,0 +1,67 @@
1#!/usr/bin/env python3
2##
3## Copyright 2015 Canonical Ltd.
4##
5## This program is free software; you can redistribute it and/or modify
6## it under the terms of the GNU General Public License as published by
7## the Free Software Foundation; version 3.
8##
9## This program is distributed in the hope that it will be useful,
10## but WITHOUT ANY WARRANTY; without even the implied warranty of
11## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12## GNU General Public License for more details.
13##
14## You should have received a copy of the GNU General Public License
15## along with this program. If not, see <http://www.gnu.org/licenses/>.
16##
17## Authors:
18## Scott Sweeny
19##
20
21import http.server
22import os
23import socketserver
24import sys
25from urllib.parse import urlparse,parse_qs
26
27def read_file(path):
28 # The path we get starts with a '/' so strip it
29 file = os.path.join(os.path.dirname(os.path.abspath(__file__)), path[1:])
30 sys.stderr.write("File Path: %s\n" % file)
31 if os.path.isfile(file):
32 with open(file, 'r') as fp:
33 content = fp.read()
34 else:
35 content = ''
36
37 return content
38
39class MyRequestHandler(http.server.BaseHTTPRequestHandler):
40 def do_GET(self):
41 sys.stderr.write("GET: %s\n" % self.path)
42 sys.stderr.flush()
43
44 parse = urlparse(self.path)
45 path = parse.path
46
47 content = read_file(path)
48 if content != '':
49 self.send_response(200)
50 self.send_header("Content-type", "application/xml")
51 self.end_headers()
52 self.wfile.write(bytes(content, 'UTF-8'))
53 else:
54 self.send_response(404)
55 self.send_header("Content-type", "text/html")
56 self.end_headers()
57 self.wfile.write(bytes('ERROR\n', 'UTF-8'))
58
59if __name__ == "__main__":
60 Handler = MyRequestHandler
61 httpd = socketserver.TCPServer(("127.0.0.1", 9999), Handler)
62
63 sys.stdout.write('%d\n' % httpd.server_address[1])
64 sys.stdout.flush()
65 httpd.serve_forever()
66
67
068
=== added directory 'tests/server/vox'
=== added directory 'tests/server/vox/rss'
=== added file 'tests/server/vox/rss/index.xml'
--- tests/server/vox/rss/index.xml 1970-01-01 00:00:00 +0000
+++ tests/server/vox/rss/index.xml 2015-05-20 13:57:15 +0000
@@ -0,0 +1,113 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
3 <title>Vox - All</title>
4 <subtitle/>
5 <icon>https://cdn3.vox-cdn.com/community_logos/52517/voxv.png</icon>
6 <updated>2015-01-22T16:20:00-05:00</updated>
7 <id>http://www.vox.com/rss/index.xml</id>
8 <link type="text/html" href="http://www.vox.com/" rel="alternate"/>
9 <entry>
10 <published>2015-01-22T16:20:00-05:00</published>
11 <updated>2015-01-22T16:20:00-05:00</updated>
12 <title>The New England Patriots' deflated footballs scandal, explained</title>
13 <content type="html">
14 &lt;img alt="" src="https://cdn3.vox-cdn.com/thumbor/3YPNccEVQeXUgjjqUexFC-LFOM0=/0x0:4915x3277/400x267/cdn0.vox-cdn.com/uploads/chorus_image/image/45507798/459836192.0.0.jpg" /&gt;
15
16
17
18 &lt;p&gt;An NFL investigation has found that 11 of the 12 footballs used by the New England Patriots during the AFC Championship were under-inflated, according to &lt;a href="https://twitter.com/mortreport/status/557748673208401921"&gt;ESPN's Chris Mortensen&lt;/a&gt;.&lt;/p&gt;
19&lt;p&gt;Why might the Patriots want under-inflated footballs? In theory, it would have made the balls easier for quarterback Tom Brady to hold and for the team's receivers to catch during the game's rainy conditions. Because teams always use their own sets of footballs when they're on offense, this wouldn't have helped their opponents, the Indianapolis Colts. For better or worse, this scandal seems to have been unofficially named &lt;a href="http://www.latimes.com/sports/nfl/la-sp-patriots-deflated-footballs-20150121-story.html"&gt;Deflate-gate&lt;/a&gt;.&lt;/p&gt;
20&lt;p&gt;On Thursday, both Patriots coach &lt;a target="_blank" href="https://twitter.com/SBNationNFL/status/558274393336725504"&gt;Bill Belichick&lt;/a&gt; and Brady denied any involvement, and the league hasn't made any official comment yet. But if the allegations are true, it could mean serious penalties for the Patriots — possibly including fines and lost draft picks. And given previous instances of cheating by the team, it could further tarnish their legacy, even if they win &lt;a href="http://en.wikipedia.org/wiki/Super_Bowl_XLIX"&gt;Super Bowl XLIX&lt;/a&gt;, giving Brady and Belichick a fourth ring together.&lt;/p&gt;
21&lt;p&gt;Here's what we know so far about the situation.&lt;/p&gt;
22&lt;h3&gt;What did the Patriots do?&lt;/h3&gt;
23
24&lt;p class="caption"&gt;Patriots coach Bill Belichick, on the sideline of the AFC Championship. (Elsa/Getty Images)&lt;/p&gt;
25&lt;p&gt;In their game on Sunday, January 18 against the Indianapolis Colts — a game in which the winner would advance to the Super Bowl — the Patriots allegedly let a bit of air out of the footballs they were using on offense.&lt;/p&gt;
26&lt;p&gt;Initially, it was reported that after catching an interception in the second quarter, Colts linebacker D'Qwell Jackson noticed the ball was less inflated than usual. On the sidelines, he passed it over to an equipment manager, and it eventually made its way to the team's general manager, then the NFL's director of football operations.&lt;/p&gt;
27&lt;p&gt;However, &lt;a style="font-size: 15px; line-height: 1.65;" href="http://www.foxsports.com/nfl/story/deflategate-baltimore-ravens-indianapolis-colts-deflated-footballs-012115" target="_blank"&gt;Fox Sports' Jay Glazer has since reported&lt;/a&gt; that the Patriots' previous opponent (the Baltimore Ravens) tipped the Colts off to the fact that their balls might be under-inflated before the game, and the NFL was already planning to inspect them.&lt;/p&gt;
28&lt;p&gt;In any event, officials checked the balls at halftime, and reportedly found that 11 of the 12 balls the Patriots were using were indeed under-inflated — with about two pounds per square inch less pressure than the minimum &lt;a href="http://static.nfl.com/static/content/public/image/rulebook/pdfs/5_2013_Ball.pdf"&gt;12.5 psi &lt;/a&gt;mandated by the league. But we still don't know the full results of the investigation.&lt;/p&gt;
29&lt;h3&gt;Why would the Patriots want to under-inflate footballs?&lt;/h3&gt;
30
31&lt;p class="caption"&gt;Patriots quarterback Tom Brady passes during the first quarter against the Colts. (Jared Wickerham/Getty Images)&lt;/p&gt;
32&lt;p&gt;The basic idea is that softer, less fully-inflated footballs are easier to hold and catch.&lt;/p&gt;
33&lt;p&gt;Given that the game was played in slick, rainy conditions — and that different footballs are used by each team (more on that below) — this could provide a slight advantage to the Patriots offense, especially for quarterback Tom Brady. &lt;span&gt;Teams use their own sets of balls whenever they're on offense, so it wouldn't have benefitted the Colts.&lt;/span&gt;&lt;/p&gt;
34&lt;p&gt;It might not make a huge difference, but &lt;a href="http://www.npr.org/blogs/thetwo-way/2015/01/20/378581349/scientists-say-the-nfls-deflate-gate-isnt-all-hot-air"&gt;materials scientists&lt;/a&gt; and &lt;a href="http://espn.go.com/nfl/playoffs/2014/story/_/id/12201369/aaron-rodgers-green-bay-packers-upset-referees-take-air-footballs"&gt;players&lt;/a&gt; confirm that letting a bit of air out could make the balls somewhat easier to hold, especially for the quarterback.&lt;/p&gt;
35&lt;h3&gt;How could the Patriots have done this?&lt;/h3&gt;
36
37&lt;p class="caption"&gt;Game balls rest in a sideline bag during a December game. (Brett Carlsen/Getty Images)&lt;/p&gt;
38&lt;p&gt;Here's how the NFL's system for game balls works: for each game, each team prepares a set of 12 balls for it to use on offense. Team equipment staff are allowed to &lt;a href="http://www.nytimes.com/2013/11/24/sports/football/eli-mannings-footballs-are-months-in-making.html?_r=0"&gt;scuff up brand-new balls&lt;/a&gt;, removing the factory shine, and allowing them to be gripped more easily by their quarterbacks.&lt;/p&gt;
39&lt;p&gt;Before the game, these balls are &lt;a href="http://mmqb.si.com/2013/12/06/peter-king-week-with-officiating-crew-part-three/2/"&gt;delivered to the officials&lt;/a&gt;, who test to see if they're inflated to somewhere between 12.5 and 13.5 pounds per square inch. If they're under-inflated, the officials add some air themselves.&lt;/p&gt;
40&lt;p&gt;Then, the balls are kept in a zipped bag on the sidelines. During the game, ball boys occasionally hand fresh balls to the officials, who put them in play.&lt;/p&gt;
41&lt;p&gt;It's unclear how or when Patriots staff might have let some of the air out of their set of balls. It'd be extremely risky to do so on the sideline, in full view of the whole stadium, but in theory, they should have been properly inflated just before the game. During press conferences on Thursday, both Belichick and Brady denied any involvement or knowledge of deflating the balls.&lt;/p&gt;
42&lt;p&gt;An even bigger mystery is how the officials — who handle the balls before every single play — didn't notice they were under-inflated, when one touch by Jackson caught his attention.&lt;/p&gt;
43
44&lt;p class="caption"&gt;Umpire Carl Paganelli handles a ball during the game. (Elsa/Getty Images)&lt;/p&gt;
45&lt;h3&gt;Could under-inflating the balls have let the Patriots win?&lt;/h3&gt;
46&lt;p&gt;Almost certainly not. The Patriots beat the Colts 45 to 7 — an especially dominant win, even for the Patriots.&lt;/p&gt;
47&lt;p&gt;Further, they scored mostly by running the ball, an area where under-inflated balls wouldn't make much of a difference.&lt;/p&gt;
48&lt;p&gt;People aren't upset because the Patriots may have won this game by under-inflating their balls. They're upset because the Patriots have been remarkably dominant for 15 years — but during that time, have consistently pushed the envelope in terms of rules, and on at least one other occasion, have been caught cheating.&lt;/p&gt;
49&lt;p&gt;If the team habitually under-inflates its game balls, it could provide a very real advantage — something that may have, in some cases, been the difference between a loss and a win.&lt;/p&gt;
50&lt;h3&gt;Is this the first time the Patriots have been accused of cheating?&lt;/h3&gt;
51
52&lt;p class="caption"&gt;Bill Belichick. (John Tlumacki/The Boston Globe via Getty Images)&lt;/p&gt;
53&lt;p&gt;Nope.&lt;/p&gt;
54&lt;p&gt;In 2007, the team was &lt;a href="http://en.wikipedia.org/wiki/2007_National_Football_League_videotaping_controversy"&gt;caught illegally filming&lt;/a&gt; the New York Jets coaching staff. Having tape of the coaches' hand signals — and being able to match them up with the actual plays run on the field — could provide a big advantage, essentially allowing Belichick and the Patriots' staff to decode opponents' signaling systems. &lt;a href="http://sports.espn.go.com/nfl/news/story?id=3392047"&gt;Belichick later admitted&lt;/a&gt; that he'd been taping opposing coaching staffs ever since becoming a head coach in 2000, and thought it was permitted by league rules.&lt;/p&gt;
55&lt;p&gt;It wasn't, and in response, the NFL fined Belichick $500,000, fined the team $250,000, and stripped the team of its first round draft pick. Around the same time, allegations surfaced that Belichick had also filmed a St. Louis Rams practice right before beating them in Super Bowl XXXVI, but he denied it.&lt;/p&gt;
56&lt;p&gt;There have also been all other sorts of unproven allegations of cheating by the Patriots. Most recently, two weeks ago, &lt;a href="http://www.cbssports.com/nfl/writer/jason-la-canfora/24981269/some-baltimore-ravens-think-footballs-were-under-inflated-vs-patriots"&gt;some Baltimore Ravens felt&lt;/a&gt; that the kicking balls they used in their playoff loss to the Patriots (a separate set of game balls used solely for kicking and punting) were under-inflated, which would have made it more difficult to kick long field goals. And during a regular season game this past November, &lt;a style="font-size: 15px; line-height: 1.65;" href="http://www.sbnation.com/2015/1/21/7867523/deflategate-deflated-balls-colts-patriots-regular-season-game" target="_blank"&gt;Colts players were reportedly suspicious&lt;/a&gt; that the Patriots were using under-inflated balls.&lt;/p&gt;
57&lt;p&gt;Even when he's playing within the rules, Belichick — smartly — likes to push the envelope in ways that aren't part of conventional football practice. In the same game against the Ravens, he used unusual formations on several plays, for instance, and &lt;a href="http://mmqb.si.com/2015/01/12/nfl-playoffs-cowboys-packers-dez-bryant-replay-catch-peyton-manning-retirement/7/"&gt;Ravens coach John Harbaugh complained&lt;/a&gt; that his team didn't have enough time to match up, as mandated by league rules.&lt;/p&gt;
58&lt;p&gt;For many fans, all this raises a question: what else have Belichick and the Patriots gotten away with?&lt;/p&gt;
59&lt;h3&gt;Is there a name for this new scandal?&lt;/h3&gt;
60&lt;p&gt;Alas. Yes. Most people seem to be calling it &lt;a href="http://www.latimes.com/sports/nfl/la-sp-patriots-deflated-footballs-20150121-story.html"&gt;Deflate-gate&lt;/a&gt;, the latest in a string of &lt;a href="http://en.wikipedia.org/wiki/List_of_scandals_with_%22-gate%22_suffix"&gt;hundreds of scandals&lt;/a&gt; with the "gate" suffix tacked on, in an allusion to &lt;a href="http://en.wikipedia.org/wiki/Watergate_scandal"&gt;Watergate&lt;/a&gt;.&lt;/p&gt;
61&lt;p&gt;It'd be great if we could figure out a more creative way to name our scandals, though, and some people have come up with the more imaginative "&lt;a target="_blank" href="http://www.gq.com/blogs/the-feed/2015/01/russell-wilson-vs-ballghazi-in-the-super-bowl.html"&gt;Ballghazi&lt;/a&gt;." It remains to be seen if it will catch on.&lt;/p&gt;
62&lt;h3&gt;What's going to happen next?&lt;/h3&gt;
63&lt;p&gt;The &lt;a href="http://www.sbnation.com/nfl/2015/1/20/7862021/superbowl-deflategate-new-england-patriots"&gt;NFL has said&lt;/a&gt; it's hoping to wrap up the investigation quickly, within a few days. That means the official results will likely be public soon — and the story will become a huge one in the week leading up to Super Bowl XLIX.&lt;/p&gt;
64&lt;p&gt;However, this scandal won't impact the Super Bowl directly. Instead, if the Patriots are found guilty, the team or Belichick might have to pay fines, and perhaps give up a draft pick in the upcoming draft, which is in April. The punishments &lt;a target="_blank" href="https://twitter.com/SI_PeterKing/status/557934211118927872"&gt;will likely be meted out&lt;/a&gt; after the Super Bowl.&lt;/p&gt;
65
66&lt;p class="caption"&gt;Bill Belichick holds the Lombardi Trophy after Super Bowl XXXVIII. (JEFF HAYNES/AFP/Getty Images)&lt;/p&gt;
67&lt;p&gt;The biggest consequence of all this is that, if found guilty, Deflate-gate could tarnish the Patriots' long-term legacy.&lt;/p&gt;
68&lt;p&gt;If they win the Super Bowl, it could cement Belichick and Brady's legacy as one of the best coach-quarterback pairings of all time — they'd become one of only two duos to ever win four Super Bowls. But having a second instance of confirmed cheating during that remarkable run might change perceptions of it in the future.&lt;/p&gt;
69&lt;hr&gt;
70&lt;h4&gt;Watch: Can the NFL survive its concussion crisis?&lt;/h4&gt;
71
72
73</content>
74 <link rel="alternate" type="text/html" href="http://www.vox.com/2015/1/21/7866121/deflated-football-patriots-cheating"/>
75 <id>http://www.vox.com/2015/1/21/7866121/deflated-football-patriots-cheating</id>
76 <author>
77 <name>Joseph Stromberg</name>
78 </author>
79 </entry>
80 <entry>
81 <published>2015-01-22T15:40:02-05:00</published>
82 <updated>2015-01-22T15:40:02-05:00</updated>
83 <title>Read McDonald's workers' shocking harassment and discrimination complaints — and why they're so important</title>
84 <content type="html">
85 &lt;img alt="" src="https://cdn2.vox-cdn.com/thumbor/3YAMFCiMs4zJnJIty3Fl402tGhY=/0x40:2039x1399/400x267/cdn0.vox-cdn.com/uploads/chorus_image/image/45516554/112561118.0.jpg" /&gt;
86
87
88
89 &lt;p&gt;Ten current and former McDonald's workers filed suit in a Virginia district court on Thursday, alleging racial discrimination and sexual harassment at McDonald's locations in two Virginia cities.&lt;/p&gt;
90&lt;p&gt;In one store, for example, one supervisor allegedly would say it was "too dark in the store" at times when most workers were African-American. And the suit goes on to list some almost unfathomably degrading behavior on the part of supervisors:&lt;/p&gt;
91&lt;blockquote&gt;
92&lt;p&gt;Plaintiffs were subjected to rampant racial and sexual harassment, committed by the restaurants' highest-ranking supervisors. Together, these supervisors demeaned African American workers; often complained that "there are too many black people in the store;" called African-American workers "bitch," "ghetto," and "ratchet;" called Hispanic workers "dirty Mexican;" disciplined African-American employees for rule infractions that were forgiven when committed by white employees; inappropriately touched female employees on their legs and buttocks; sent female employees sexual pictures; and solicited sexual relations from female employees.&lt;/p&gt;
93&lt;/blockquote&gt;
94&lt;p&gt;The allegations in the lawsuit are of course shocking on a basic level. But this suit is also important in a much subtler way, in that it's filed against both Soweva — the franchisee operating these stores — and the McDonald's corporation itself. Far more than being a simply discrimination and harassment suit, this case is another example of a question that has repeatedly been raised in labor law in the last year — when is an big chain a "joint employer" of people who work for one of its franchises?&lt;/p&gt;
95&lt;p&gt;In other words, can McDonald's and other corporations be held legally accountable for the working conditions endured by front-line employees who wear their uniforms but are technically employees of independently owned franchises? This seemingly pedantic question actually has broad implications for many franchise-heavy industries (fast food, hotels, gyms) and how they relate to their workers — how they schedule employees and negotiate with unions, for example.&lt;/p&gt;
96&lt;h3&gt;A bigger, nationwide debate&lt;/h3&gt;
97&lt;p&gt;The franchising debate has heated up with a few high-profile cases. In California, for example, the supreme court &lt;a href="http://blogs.orrick.com/employment/2014/09/30/dominos-delivers-key-ruling-in-favor-of-franchisors/" target="_blank"&gt;last year&lt;/a&gt; ultimately ruled in favor of Domino's Pizza, saying it was not a joint employer along with its franchise operators. A &lt;a href="http://www.vox.com/2014/12/19/7420729/nlrb-browning-ferris-employer"&gt;yet-to-be-decided case&lt;/a&gt; before the National Labor Relations Board questions whether a waste management company is an employer along with its subcontractors. And in December, the NLRB decided to authorize complaints against both franchise operators and the McDonald's parent company, alleging retaliation against employees who participated in protests demanding $15-per-hour wages. Even though that was a preliminary decision, it was considered a big win for labor-rights advocates.&lt;/p&gt;
98&lt;p&gt;These sorts of cases could strike at the heart of the franchisor-franchisee relationship, in which the franchisee runs the business according to certain specifications set by the parent company but operates independently in many other ways, like in how it treats its employees. That often means a franchisee acts as a sort of buffer between workers and the parent corporation.&lt;/p&gt;
99&lt;p&gt;But the question of joint employership is being reconsidered lately. The NLRB, for example, &lt;a href="http://www.whitecase.com/files/Publication/65ab18cc-ecf9-4c2f-9719-4642b26cb61c/Presentation/PublicationAttachment/5cccd1d1-a9c9-4660-9dd3-4a7a8475ece5/would-you-like-joint-employer-liability-mcdonalds-serves-cautionary-tal.pdf"&gt;appears willing&lt;/a&gt; to reconsider that definition, which currently says an employer must have "direct and immediate impact" on the terms and conditions of workers' employment — for example, having a say in hiring and firing, as well as wage-setting.&lt;/p&gt;
100&lt;p&gt;In this case, plaintiffs are saying that McDonald's is partially liable because it had so much control over its stores. The lawsuit references McDonald's' detailed training manuals, control over menus, and routine visits from McDonald's mystery shoppers as examples of the parent company's control over stores. And in a call with reporters, plaintiff Katrina Stanfield said she complained to McDonald's about the harassment and discrimination and that they did nothing in response.&lt;/p&gt;
101&lt;h3&gt;The repercussions of a new definition could be huge&lt;/h3&gt;
102&lt;p&gt;According to one attorney, when the definition is murky, it makes operating those businesses difficult.&lt;/p&gt;
103&lt;p&gt;"If you don't know who the employer is, you can't allocate liability, and you really don't know how to run your business," says Michael Lotito, co-chair of the Workplace Policy Institute at law firm Littler Mendelson.&lt;/p&gt;
104&lt;p&gt;And if pending cases do indeed find parent companies to be liable for their franchisees' wrongdoings, it could have repercussions far beyond McDonald's. &lt;span&gt;And the broader question of what, exactly, is an "employer" could even affect the relationships between, for example, retailers and suppliers, as well as employers and staffing agencies. &lt;/span&gt;&lt;span&gt;Of course, neither the NLRB nor Virginia's District Court has the last word. Settling this question could be a years-long process, says Lotito, and decisions could differ from jurisdiction to jurisdiction. And given that groups like SEIU and Fast Food Forward are fighting hard on this question, expect to hear more about the joint employer issue in the years to come.&lt;/span&gt;&lt;/p&gt;
105
106</content>
107 <link rel="alternate" type="text/html" href="http://www.vox.com/2015/1/22/7873661/mcdonalds-lawsuit-harassment-discrimination"/>
108 <id>http://www.vox.com/2015/1/22/7873661/mcdonalds-lawsuit-harassment-discrimination</id>
109 <author>
110 <name>Danielle Kurtzleben</name>
111 </author>
112 </entry>
113</feed>
0114
=== added directory 'tests/server/xataka'
=== added file 'tests/server/xataka/xataka2.xml'
--- tests/server/xataka/xataka2.xml 1970-01-01 00:00:00 +0000
+++ tests/server/xataka/xataka2.xml 2015-05-20 13:57:15 +0000
@@ -0,0 +1,6 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2spanishfull.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.weblogssl.com/~d/styles/itemcontent.css"?><rss xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>Xataka</title><link>http://www.xataka.com</link><description>Publicación de noticias sobre gadgets y tecnología. Últimas tecnologías en electrónica de consumo y novedades tecnológicas en móviles, tablets, informática, etc</description><language>en</language><pubDate>Wed, 21 Jan 2015 23:14:01 GMT</pubDate><lastBuildDate>Wed, 21 Jan 2015 23:14:01 GMT</lastBuildDate><ttl>2</ttl><feedburner:info uri="xataka2" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" /><image><link>http://xataka.com</link><url>http://img.weblogssl.com/g/recursos/planet/xataka.jpg</url><title>Xataka | blog de gadgets y electrónica de consumo</title></image><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://xataka.com/atom.xml" /><feedburner:feedFlare href="http://add.my.yahoo.com/content?lg=es&amp;url=http%3A%2F%2Fxataka.com%2Fatom.xml" src="http://eur.i1.yimg.com/eur.yimg.com/i/es/my/addto1.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Fxataka.com%2Fatom.xml" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Fxataka.com%2Fatom.xml" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.plusmo.com/add?url=http%3A%2F%2Fxataka.com%2Fatom.xml" src="http://plusmo.com/res/graphics/fbplusmo.gif">Subscribe with Plusmo</feedburner:feedFlare><feedburner:feedFlare href="http://www.thefreedictionary.com/_/hp/AddRSS.aspx?http%3A%2F%2Fxataka.com%2Fatom.xml" src="http://img.tfd.com/hp/addToTheFreeDictionary.gif">Subscribe with The Free Dictionary</feedburner:feedFlare><feedburner:feedFlare href="http://www.bitty.com/manual/?contenttype=rssfeed&amp;contentvalue=http%3A%2F%2Fxataka.com%2Fatom.xml" src="http://www.bitty.com/img/bittychicklet_91x17.gif">Subscribe with Bitty Browser</feedburner:feedFlare><feedburner:feedFlare href="http://www.live.com/?add=http%3A%2F%2Fxataka.com%2Fatom.xml" src="http://tkfiles.storage.msn.com/x1piYkpqHC_35nIp1gLE68-wvzLZO8iXl_JMledmJQXP-XTBOLfmQv4zhj4MhcWEJh_GtoBIiAl1Mjh-ndp9k47If7hTaFno0mxW9_i3p_5qQw">Subscribe with Live.com</feedburner:feedFlare><feedburner:feedFlare href="http://mix.excite.eu/add?feedurl=http%3A%2F%2Fxataka.com%2Fatom.xml" src="http://image.excite.co.uk/mix/addtomix.gif">Subscribe with Excite MIX</feedburner:feedFlare><feedburner:feedFlare href="http://www.webwag.com/wwgthis.php?url=http%3A%2F%2Fxataka.com%2Fatom.xml" src="http://www.webwag.com/images/wwgthis.gif">Subscribe with Webwag</feedburner:feedFlare><feedburner:feedFlare href="http://www.podcastready.com/oneclick_bookmark.php?url=http%3A%2F%2Fxataka.com%2Fatom.xml" src="http://www.podcastready.com/images/podcastready_button.gif">Subscribe with Podcast Ready</feedburner:feedFlare><feedburner:feedFlare href="http://www.wikio.com/subscribe?url=http%3A%2F%2Fxataka.com%2Fatom.xml" src="http://www.wikio.com/shared/img/add2wikio.gif">Subscribe with Wikio</feedburner:feedFlare><feedburner:feedFlare href="http://www.dailyrotation.com/index.php?feed=http%3A%2F%2Fxataka.com%2Fatom.xml" src="http://www.dailyrotation.com/rss-dr2.gif">Subscribe with Daily Rotation</feedburner:feedFlare><feedburner:browserFriendly>Esta es la fuente o feed para suscripción de Xataka. Vale para cualquier formato (RSS, Atom, lo que sea). Aunque salga esta página "rara" en vez del código habitual, es lo mismo. De verdad.</feedburner:browserFriendly><item><title>En Samsung ya preparan la mudanza, sus nuevas oficinas en Silicon Valley están casi listas</title><link>http://feeds.weblogssl.com/~r/xataka2/~3/sN5HXQsOYCA/en-samsung-ya-preparan-la-mudanza-sus-nuevas-oficinas-en-silicon-valley-estan-casi-listas</link><description>&lt;p&gt;&lt;img alt="Samsung Hq Silicon Valley" src="http://img.xataka.com/2015/01/650_1000_samsung_hq_silicon_valley.jpg" class="centro_sinmarco" /&gt;&lt;/p&gt; &lt;p&gt;Hace un año &lt;a href="http://www.xataka.com/otros/asi-sera-el-campus-con-el-que-samsung-quiere-enamorar-a-eeuu"&gt;Samsung nos presumía&lt;/a&gt; su nuevo gran proyecto con el que entrarían de lleno con &lt;strong&gt;presencia &lt;em&gt;in-situ&lt;/em&gt; en los Estados Unidos&lt;/strong&gt;, sus nuevos cuarteles centrales en el centro neurálgico de la tecnología en el mundo, Silicon Valley.&lt;/p&gt; &lt;p&gt;Pero Samsung no sólo se está limitando a construir sus nuevas oficinas, sino que también quieren adelantarse y ser &lt;strong&gt;los primeros en echarlas a andar&lt;/strong&gt;, porque recordemos que tanto &lt;a href="http://www.applesfera.com/apple-1/apple-presenta-su-futuro-campus-en-un-video-que-rescata-la-voz-de-steve-jobs"&gt;Apple&lt;/a&gt;, como Google y Facebook tienen actualmente importantes proyectos de expansión en sus oficinas dentro de California.&lt;!--more--&gt;&lt;/p&gt; &lt;h2&gt;Samsung quiere concentrar esfuerzos en EE.UU. y Latinoamérica&lt;/h2&gt; &lt;p&gt;Estás oficinas serán una expansión del negocio de semiconductores, memorias, almacenamiento y paneles LCD, además de que un gran equipo de ventas con sede en Corea del Sur se mudará a este nuevo complejo, la idea es clara, &lt;strong&gt;reducir costes de traslado y operación&lt;/strong&gt; hacia uno de los mercados más importantes de la compañía, Estados Unidos, donde además también tendrán cobertura en negocios dentro de Latinoamérica.&lt;/p&gt; &lt;p&gt;&lt;img alt="Samsung Hq Silicon Valley 01" src="http://img.xataka.com/2015/01/650_1000_samsung_hq_silicon_valley_01.jpg" class="centro_sinmarco" /&gt;&lt;/p&gt; &lt;p&gt;El nuevo campus contará con diez plantas divididas en dos edificios conectados entre sí, con una &lt;strong&gt;nueva área de investigación y desarrollo&lt;/strong&gt;, abarcando una superficie de poco más de 10 hectáreas, todo bajo un diseño del estudio de arquitectura &lt;a href="http://www.nbbj.com/work/samsung-america-headquarters/"&gt;NBBJ&lt;/a&gt;, famoso por los desarrollos de Google, Amazon, Alipay en China, entre otros.&lt;/p&gt; &lt;p&gt;El concepto que busca transmitir Samsung en este nuevo campus es hacia el estilo de &lt;strong&gt;trabajo colaborativo&lt;/strong&gt;, ya que el diseño es en torno a un gran patio central, de tal manera que todos los que trabajan ahí puedan salir a los pasillos e interactuar con sus otros compañeros de otros pisos, además se contará con un centro de acondicionamiento físico, con canchas de baloncesto, y un centro de interacción con cafeterías y mesas dentro de un parque para ayudar con dicha convivencia.&lt;/p&gt; &lt;p&gt;&lt;img alt="Samsung Hq Silicon Valley 02" src="http://img.xataka.com/2015/01/650_1000_samsung_hq_silicon_valley_02.jpg" class="centro_sinmarco" /&gt;&lt;/p&gt; &lt;p&gt;Los materiales usados son principalmente metal blanco, cristal y jardines, ya que la idea es reducir el calor al interior, transmitir &lt;strong&gt;sensación de ligereza&lt;/strong&gt; y tener siempre una vista hacia el exterior. El proyecto que ha costado 300 millones de dólares y que albergará hasta 2.500 trabajadores, ha llegado a su etapa final y han confirmando su apertura durante julio próximo. &lt;/p&gt; &lt;p&gt;Con esto se esperan reacciones sobre todo de empresas extranjeras, ya que el gobierno de California está &lt;strong&gt;otorgando apoyos&lt;/strong&gt; para que todas aquellas compañías que quieran entrar y formar parte de los nuevos desarrollos, sobre todo en San José, incrementen el valor de la ciudad, concentrando así a las empresas de tecnología en un solo lugar.&lt;/p&gt; &lt;p&gt;&lt;iframe width="650" height="366" src="//player.vimeo.com/video/70145380?title=0&amp;#38;byline=0&amp;#38;frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen&gt;&lt;/iframe&gt;&lt;/p&gt; &lt;p&gt;&lt;p&gt; &lt;strong&gt;nuevo-campus-de-samsung-en-silicon-valley&lt;/strong&gt; &lt;/p&gt; &lt;p&gt; &lt;a href="http://www.xataka.com/galeria/nuevo-campus-de-samsung-en-silicon-valley/1"&gt; &lt;img src="http://img.xataka.com/galleries/nuevo-campus-de-samsung-en-silicon-valley/120_120_Samsung-6936-728x600.jpg" alt="image01" data-type="gallery"/&gt; &lt;/a&gt; &lt;a href="http://www.xataka.com/galeria/nuevo-campus-de-samsung-en-silicon-valley/2"&gt; &lt;img src="http://img.xataka.com/galleries/nuevo-campus-de-samsung-en-silicon-valley/120_120_Samsung-6958-800x533.jpg" alt="image01" data-type="gallery"/&gt; &lt;/a&gt; &lt;a href="http://www.xataka.com/galeria/nuevo-campus-de-samsung-en-silicon-valley/3"&gt; &lt;img src="http://img.xataka.com/galleries/nuevo-campus-de-samsung-en-silicon-valley/120_120_Samsung-6971-677x600.jpg" alt="image01" data-type="gallery"/&gt; &lt;/a&gt; &lt;a href="http://www.xataka.com/galeria/nuevo-campus-de-samsung-en-silicon-valley/4"&gt; &lt;img src="http://img.xataka.com/galleries/nuevo-campus-de-samsung-en-silicon-valley/120_120_Samsung-69971.jpg" alt="image01" data-type="gallery"/&gt; &lt;/a&gt; &lt;/p&gt;&lt;/p&gt; &lt;p&gt;Vía | &lt;a href="http://www.wired.com/2015/01/photos-samsungs-giant-new-silicon-valley-hq-almost-complete/"&gt;Wired&lt;/a&gt;&lt;/p&gt; &lt;p&gt; - &lt;br/&gt; La noticia &lt;a href="http://www.xataka.com/otros/en-samsung-ya-preparan-la-mudanza-sus-nuevas-oficinas-en-silicon-valley-estan-casi-listas?utm_source=feedburner&amp;utm_medium=feed&amp;utm_campaign=22_Jan_2015"&gt; &lt;em&gt; En Samsung ya preparan la mudanza, sus nuevas oficinas en Silicon Valley están casi listas &lt;/em&gt; &lt;/a&gt; fue publicada originalmente en &lt;a href="http://www.xataka.com?utm_source=feedburner&amp;utm_medium=feed&amp;utm_campaign=22_Jan_2015"&gt; &lt;strong&gt; Xataka &lt;/strong&gt; &lt;/a&gt; por &lt;a href="http://www.xataka.com/autor/raul-alvarez?utm_source=feedburner&amp;utm_medium=feed&amp;utm_campaign=22_Jan_2015"&gt; Raúl Álvarez &lt;/a&gt; . &lt;/p&gt;&lt;img width='1' height='1' src='http://weblogs.feedsportal.com/c/32673/f/502913/s/4291eb56/sc/28/mf.gif' border='0'/&gt;&lt;br clear='all'/&gt;&lt;br/&gt;&lt;br/&gt;&lt;a href="http://da.feedsportal.com/r/218610885794/u/49/f/502913/c/32673/s/4291eb56/sc/28/rc/1/rc.htm" rel="nofollow"&gt;&lt;img src="http://da.feedsportal.com/r/218610885794/u/49/f/502913/c/32673/s/4291eb56/sc/28/rc/1/rc.img" border="0"/&gt;&lt;/a&gt;&lt;br/&gt;&lt;a href="http://da.feedsportal.com/r/218610885794/u/49/f/502913/c/32673/s/4291eb56/sc/28/rc/2/rc.htm" rel="nofollow"&gt;&lt;img src="http://da.feedsportal.com/r/218610885794/u/49/f/502913/c/32673/s/4291eb56/sc/28/rc/2/rc.img" border="0"/&gt;&lt;/a&gt;&lt;br/&gt;&lt;a href="http://da.feedsportal.com/r/218610885794/u/49/f/502913/c/32673/s/4291eb56/sc/28/rc/3/rc.htm" rel="nofollow"&gt;&lt;img src="http://da.feedsportal.com/r/218610885794/u/49/f/502913/c/32673/s/4291eb56/sc/28/rc/3/rc.img" border="0"/&gt;&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;&lt;a href="http://da.feedsportal.com/r/218610885794/u/49/f/502913/c/32673/s/4291eb56/sc/28/a2.htm"&gt;&lt;img src="http://da.feedsportal.com/r/218610885794/u/49/f/502913/c/32673/s/4291eb56/sc/28/a2.img" border="0"/&gt;&lt;/a&gt;&lt;img width="1" height="1" src="http://pi.feedsportal.com/r/218610885794/u/49/f/502913/c/32673/s/4291eb56/sc/28/a2t.img" border="0"/&gt;&lt;div class="feedflare"&gt;
3&lt;a href="http://feeds.weblogssl.com/~ff/xataka2?a=sN5HXQsOYCA:zZYjFGREknA:3QFJfmc7Om4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/xataka2?i=sN5HXQsOYCA:zZYjFGREknA:3QFJfmc7Om4" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.weblogssl.com/~ff/xataka2?a=sN5HXQsOYCA:zZYjFGREknA:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/xataka2?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.weblogssl.com/~ff/xataka2?a=sN5HXQsOYCA:zZYjFGREknA:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/xataka2?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.weblogssl.com/~ff/xataka2?a=sN5HXQsOYCA:zZYjFGREknA:ecdYMiMMAMM"&gt;&lt;img src="http://feeds.feedburner.com/~ff/xataka2?d=ecdYMiMMAMM" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
4&lt;/div&gt;&lt;img src="//feeds.feedburner.com/~r/xataka2/~4/sN5HXQsOYCA" height="1" width="1" alt=""/&gt;</description><pubDate>Wed, 21 Jan 2015 22:00:58 GMT</pubDate><guid isPermaLink="false">http://www.xataka.com/otros/en-samsung-ya-preparan-la-mudanza-sus-nuevas-oficinas-en-silicon-valley-estan-casi-listas</guid><dc:creator>Raúl Álvarez</dc:creator><feedburner:origLink>http://www.xataka.com/otros/en-samsung-ya-preparan-la-mudanza-sus-nuevas-oficinas-en-silicon-valley-estan-casi-listas</feedburner:origLink></item><item><title>Project HoloLens: así ve Microsoft el futuro del ordenador personal</title><link>http://feeds.weblogssl.com/~r/xataka2/~3/j6xSZORTEeo/project-hololens-asi-ve-microsoft-el-futuro-del-ordenador-personal</link><description>&lt;p&gt;&lt;img alt="D76d1d6c A4e6 41d2 Bc43 C9b49041a219" src="http://img.xataka.com/2015/01/650_1000_d76d1d6c-a4e6-41d2-bc43-c9b49041a219.png" class="centro_sinmarco" /&gt;&lt;/p&gt; &lt;p&gt;La gran sorpresa, y llevamos unas cuantas, de Microsoft en su evento sobre Windows 10 ha sido &lt;strong&gt;Windows Holographic&lt;/strong&gt;. En fase de desarrollo, nos da una idea de &lt;strong&gt;cómo ve Microsoft el futuro del ordenador personal&lt;/strong&gt;.&lt;/p&gt; &lt;p&gt;Holographic basa la experiencia en un ordenador llamado &lt;strong&gt;HoloLens&lt;/strong&gt; que llevamos colocado sobre la cabeza como unas gafas de &lt;strong&gt;realidad aumentada&lt;/strong&gt; y que superponen holografía en nuestro entorno para poder interactuar con él. &lt;/p&gt; &lt;!--more--&gt; &lt;p&gt;&lt;iframe width="650" height="366" src="http://www.youtube.com/embed/aThCr0PsyuA" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;/p&gt; &lt;h3&gt;Un ordenador personal colocado en la cabeza&lt;/h3&gt; &lt;p&gt;Hololens incluye un ordenador completo, con CPU, GPU, sensores y pantalla HD, además de &lt;strong&gt;una cámara similar a Kinect para identificar lo que nos rodea&lt;/strong&gt; y los gestos que hacemos con nuestras manos o la voz. Todo es inalámbrico y con funcionamiento autónomo.&lt;/p&gt; &lt;p&gt;&lt;img alt="68d91e7d 0ec2 45fb 899d 612b546550ea 1" src="http://img.xataka.com/2015/01/650_1000_68d91e7d-0ec2-45fb-899d-612b546550ea-1.jpg" class="centro_sinmarco" /&gt;&lt;/p&gt; &lt;p&gt;Aunque queda por ver cómo quedará finalmente, las demostraciones han sido muy positivas. Microsoft afirma que Holographic llegará de la mano de Windows 10 y ya hay un programa, &lt;strong&gt;Holostudio&lt;/strong&gt;, para que se puedan crear experiencias, aplicaciones y formas de interactuar con todo lo que nos rodea.&lt;/p&gt; &lt;p&gt;&lt;img alt="Ef989fe2 5c9b 4437 Ad74 Eebf34fbb625 1" src="http://img.xataka.com/2015/01/650_1000_ef989fe2-5c9b-4437-ad74-eebf34fbb625-1.jpg" class="centro_sinmarco" /&gt;&lt;/p&gt; &lt;p&gt; - &lt;br/&gt; La noticia &lt;a href="http://www.xataka.com/ordenadores/project-hololens-asi-ve-microsoft-el-futuro-del-ordenador-personal?utm_source=feedburner&amp;utm_medium=feed&amp;utm_campaign=22_Jan_2015"&gt; &lt;em&gt; Project HoloLens: así ve Microsoft el futuro del ordenador personal &lt;/em&gt; &lt;/a&gt; fue publicada originalmente en &lt;a href="http://www.xataka.com?utm_source=feedburner&amp;utm_medium=feed&amp;utm_campaign=22_Jan_2015"&gt; &lt;strong&gt; Xataka &lt;/strong&gt; &lt;/a&gt; por &lt;a href="http://www.xataka.com/autor/javier-penalva?utm_source=feedburner&amp;utm_medium=feed&amp;utm_campaign=22_Jan_2015"&gt; Javier Penalva &lt;/a&gt; . &lt;/p&gt;&lt;img width='1' height='1' src='http://weblogs.feedsportal.com/c/32673/f/502913/s/429043c6/sc/28/mf.gif' border='0'/&gt;&lt;br clear='all'/&gt;&lt;br/&gt;&lt;br/&gt;&lt;a href="http://da.feedsportal.com/r/218610893961/u/49/f/502913/c/32673/s/429043c6/sc/28/rc/1/rc.htm" rel="nofollow"&gt;&lt;img src="http://da.feedsportal.com/r/218610893961/u/49/f/502913/c/32673/s/429043c6/sc/28/rc/1/rc.img" border="0"/&gt;&lt;/a&gt;&lt;br/&gt;&lt;a href="http://da.feedsportal.com/r/218610893961/u/49/f/502913/c/32673/s/429043c6/sc/28/rc/2/rc.htm" rel="nofollow"&gt;&lt;img src="http://da.feedsportal.com/r/218610893961/u/49/f/502913/c/32673/s/429043c6/sc/28/rc/2/rc.img" border="0"/&gt;&lt;/a&gt;&lt;br/&gt;&lt;a href="http://da.feedsportal.com/r/218610893961/u/49/f/502913/c/32673/s/429043c6/sc/28/rc/3/rc.htm" rel="nofollow"&gt;&lt;img src="http://da.feedsportal.com/r/218610893961/u/49/f/502913/c/32673/s/429043c6/sc/28/rc/3/rc.img" border="0"/&gt;&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;&lt;a href="http://da.feedsportal.com/r/218610893961/u/49/f/502913/c/32673/s/429043c6/sc/28/a2.htm"&gt;&lt;img src="http://da.feedsportal.com/r/218610893961/u/49/f/502913/c/32673/s/429043c6/sc/28/a2.img" border="0"/&gt;&lt;/a&gt;&lt;img width="1" height="1" src="http://pi.feedsportal.com/r/218610893961/u/49/f/502913/c/32673/s/429043c6/sc/28/a2t.img" border="0"/&gt;&lt;div class="feedflare"&gt;
5&lt;a href="http://feeds.weblogssl.com/~ff/xataka2?a=j6xSZORTEeo:UiKlTkuHu-E:3QFJfmc7Om4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/xataka2?i=j6xSZORTEeo:UiKlTkuHu-E:3QFJfmc7Om4" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.weblogssl.com/~ff/xataka2?a=j6xSZORTEeo:UiKlTkuHu-E:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/xataka2?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.weblogssl.com/~ff/xataka2?a=j6xSZORTEeo:UiKlTkuHu-E:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/xataka2?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.weblogssl.com/~ff/xataka2?a=j6xSZORTEeo:UiKlTkuHu-E:ecdYMiMMAMM"&gt;&lt;img src="http://feeds.feedburner.com/~ff/xataka2?d=ecdYMiMMAMM" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
6&lt;/div&gt;&lt;img src="//feeds.feedburner.com/~r/xataka2/~4/j6xSZORTEeo" height="1" width="1" alt=""/&gt;</description><pubDate>Wed, 21 Jan 2015 18:17:22 GMT</pubDate><guid isPermaLink="false">http://www.xataka.com/ordenadores/project-hololens-asi-ve-microsoft-el-futuro-del-ordenador-personal</guid><dc:creator>Javier Penalva</dc:creator><feedburner:origLink>http://www.xataka.com/ordenadores/project-hololens-asi-ve-microsoft-el-futuro-del-ordenador-personal</feedburner:origLink></item></channel></rss>
07
=== added directory 'tests/unit'
=== added file 'tests/unit/CMakeLists.txt'
--- tests/unit/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ tests/unit/CMakeLists.txt 2015-05-20 13:57:15 +0000
@@ -0,0 +1,34 @@
1
2add_definitions(
3 -DTEST_SCOPE_DIRECTORY="${CMAKE_CURRENT_SOURCE_DIR}"
4 -DFAKE_RSS_SERVER="${CMAKE_CURRENT_SOURCE_DIR}/server.py"
5)
6
7# Our test executable.
8# It includes the object code from the scope
9add_executable(
10 scope-unit-tests
11 scope/test-scope.cpp
12 $<TARGET_OBJECTS:scope-static>
13)
14
15# Link against the scope, and all of our test lib dependencies
16target_link_libraries(
17 scope-unit-tests
18 ${GTEST_BOTH_LIBRARIES}
19 ${GMOCK_LIBRARIES}
20 ${SCOPE_LDFLAGS}
21 ${TEST_LDFLAGS}
22 ${Boost_LIBRARIES}
23)
24
25qt5_use_modules(
26 scope-unit-tests
27 Core
28)
29
30# Register the test with CTest
31add_test(
32 scope-unit-tests
33 scope-unit-tests
34)
035
=== added directory 'tests/unit/bbc'
=== added file 'tests/unit/bbc/CMakeLists.txt'
--- tests/unit/bbc/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ tests/unit/bbc/CMakeLists.txt 2015-05-20 13:57:15 +0000
@@ -0,0 +1,31 @@
1#for desktop dev
2configure_file(
3 "scope.ini.in"
4 "${CMAKE_BINARY_DIR}/src/scope.ini"
5)
6#this is the basis for localization
7configure_file(
8 "scope.ini.in"
9 "${CMAKE_SOURCE_DIR}/data/scope.ini"
10)
11
12INSTALL(DIRECTORY "images" DESTINATION "${SCOPE_INSTALLDIR}")
13
14# for desktop dev
15configure_file(departments.json ../src/departments.json)
16
17INSTALL(
18 FILES "scope.ini"
19 DESTINATION ${SCOPE_INSTALLDIR}
20 RENAME "${PKG_PREFIX}.${PKG}_${APP}.ini"
21)
22
23INSTALL(
24 FILES departments.json
25 DESTINATION ${SCOPE_INSTALLDIR}
26)
27
28INSTALL(
29 DIRECTORY "images"
30 DESTINATION ${SCOPE_INSTALLDIR}
31)
032
=== added directory 'tests/unit/bbc/caching'
=== added file 'tests/unit/bbc/feeds.json'
--- tests/unit/bbc/feeds.json 1970-01-01 00:00:00 +0000
+++ tests/unit/bbc/feeds.json 2015-05-20 13:57:15 +0000
@@ -0,0 +1,62 @@
1[
2 {
3 "label": "News",
4 "id": "http://127.0.0.1:9999/bbc/news/rss.xml"
5 },
6 {
7 "label": "World",
8 "id": "http://127.0.0.1:9999/bbc/news/world/rss.xml"
9 },
10 {
11 "label": "UK",
12 "id": "http://127.0.0.1:9999/bbc/news/uk/rss.xml"
13 },
14 {
15 "label": "Business",
16 "id": "http://127.0.0.1:9999/bbc/news/business/rss.xml"
17 },
18 {
19 "label": "Politics",
20 "id": "http://127.0.0.1:9999/bbc/news/politics/rss.xml"
21 },
22 {
23 "label": "Health",
24 "id": "http://127.0.0.1:9999/bbc/news/health/rss.xml"
25 },
26 {
27 "label": "Education",
28 "id": "http://127.0.0.1:9999/bbc/news/education/rss.xml"
29 },
30 {
31 "label": "Science and Environment",
32 "id": "http://127.0.0.1:9999/bbc/news/science_and_environment/rss.xml"
33 },
34 {
35 "label": "Technology",
36 "id": "http://127.0.0.1:9999/bbc/news/technology/rss.xml"
37 },
38 {
39 "label": "Entertainment and Arts",
40 "id": "http://127.0.0.1:9999/bbc/news/entertainment_and_arts/rss.xml"
41 },
42 {
43 "label": "Nature",
44 "id": "http://127.0.0.1:9999/bbc/nature/wildlife/by/latest.rss",
45 "layout": "large"
46 },
47 {
48 "label": "Magazine",
49 "id": "http://127.0.0.1:9999/bbc/news/magazine/rss.xml",
50 "layout": "carousel"
51 },
52 {
53 "label": "In Pictures",
54 "id": "http://127.0.0.1:9999/bbc/news/in_pictures/rss.xml",
55 "layout": "large"
56 },
57 {
58 "label": "Special Reports",
59 "id": "http://127.0.0.1:9999/bbc/news/special_reports/rss.xml",
60 "layout": "journal"
61 }
62]
063
=== added file 'tests/unit/bbc/icon.png'
1Binary files tests/unit/bbc/icon.png 1970-01-01 00:00:00 +0000 and tests/unit/bbc/icon.png 2015-05-20 13:57:15 +0000 differ64Binary files tests/unit/bbc/icon.png 1970-01-01 00:00:00 +0000 and tests/unit/bbc/icon.png 2015-05-20 13:57:15 +0000 differ
=== added directory 'tests/unit/bbc/images'
=== added file 'tests/unit/bbc/images/default.png'
2Binary files tests/unit/bbc/images/default.png 1970-01-01 00:00:00 +0000 and tests/unit/bbc/images/default.png 2015-05-20 13:57:15 +0000 differ65Binary files tests/unit/bbc/images/default.png 1970-01-01 00:00:00 +0000 and tests/unit/bbc/images/default.png 2015-05-20 13:57:15 +0000 differ
=== added file 'tests/unit/bbc/images/error.png'
3Binary files tests/unit/bbc/images/error.png 1970-01-01 00:00:00 +0000 and tests/unit/bbc/images/error.png 2015-05-20 13:57:15 +0000 differ66Binary files tests/unit/bbc/images/error.png 1970-01-01 00:00:00 +0000 and tests/unit/bbc/images/error.png 2015-05-20 13:57:15 +0000 differ
=== added file 'tests/unit/bbc/images/header-bbc-news.png'
4Binary files tests/unit/bbc/images/header-bbc-news.png 1970-01-01 00:00:00 +0000 and tests/unit/bbc/images/header-bbc-news.png 2015-05-20 13:57:15 +0000 differ67Binary files tests/unit/bbc/images/header-bbc-news.png 1970-01-01 00:00:00 +0000 and tests/unit/bbc/images/header-bbc-news.png 2015-05-20 13:57:15 +0000 differ
=== added file 'tests/unit/bbc/images/headerLogo.svg'
--- tests/unit/bbc/images/headerLogo.svg 1970-01-01 00:00:00 +0000
+++ tests/unit/bbc/images/headerLogo.svg 2015-05-20 13:57:15 +0000
@@ -0,0 +1,80 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!-- Created with Inkscape (http://www.inkscape.org/) -->
3
4<svg
5 xmlns:dc="http://purl.org/dc/elements/1.1/"
6 xmlns:cc="http://creativecommons.org/ns#"
7 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
8 xmlns:svg="http://www.w3.org/2000/svg"
9 xmlns="http://www.w3.org/2000/svg"
10 xmlns:xlink="http://www.w3.org/1999/xlink"
11 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
12 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
13 id="svg2"
14 version="1.1"
15 inkscape:version="0.48.4 r9939"
16 width="84"
17 height="24"
18 sodipodi:docname="logo.png">
19 <metadata
20 id="metadata8">
21 <rdf:RDF>
22 <cc:Work
23 rdf:about="">
24 <dc:format>image/svg+xml</dc:format>
25 <dc:type
26 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
27 <dc:title></dc:title>
28 </cc:Work>
29 </rdf:RDF>
30 </metadata>
31 <defs
32 id="defs6" />
33 <sodipodi:namedview
34 pagecolor="#ffffff"
35 bordercolor="#666666"
36 borderopacity="1"
37 objecttolerance="10"
38 gridtolerance="10"
39 guidetolerance="10"
40 inkscape:pageopacity="0"
41 inkscape:pageshadow="2"
42 inkscape:window-width="640"
43 inkscape:window-height="480"
44 id="namedview4"
45 showgrid="false"
46 inkscape:zoom="3.8571429"
47 inkscape:cx="42"
48 inkscape:cy="12"
49 inkscape:window-x="49"
50 inkscape:window-y="24"
51 inkscape:window-maximized="0"
52 inkscape:current-layer="svg2" />
53 <image
54 width="84"
55 height="24"
56 xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFQAAAAYCAYAAABk8drWAAAABHNCSVQICAgIfAhkiAAABA1JREFU
57WIXt2VuIlVUUB/DfNJppimZ2May0LEQr0ekqlljEdKUL9RBdHiNCCKQSgh6yDKKHrJ4KglIyygJ7
58qSgpuotW9pKlINloU3Shm6alM6eH9R3nm2/OOe0534eQ+YePWXv2Pmuts/Za6/vvfTq6urpqDgw6
59cvJBa/OwA2Hk/4RDAa0YI1rM/YjnRakUS2cczsAcjKrQn71YgV/RWbA5CqfifIyv0GYR32A9NuIL
60/IZJOBOzMBvTDY7JfnS06KGfY67WvWcensGMBEdT+tlOzMT2FnpOwhO4piKbdXyLB8WG7m6xbiQu
61xCJcV5xMLfkOkc0jCk5+hIuxKVFPip28/rrNvJ89uBavVGQT1ojMe8pAMDtxHE7O/tYrZi/exlIN
62Nik1oKfgU1ECn+BpHJ/NfScypmqMxhv4SpTfGpyXm78Puyqw8xKux8/ZeCLuFsmyRSTLFmzAk6Ll
63QH8jZa16aB5HiFKsr5+LMbglG78ndm5kor4UdOJ0nJiNzxJ9e7YI5BZsznxpF5txh4FMuxTPYXKD
64tXOyZxHewWvYp/CdUwPaqP9My8nFUq0CtQZ2j8aRqslMeBS/ZPJ8vCoq49+wMHuGYDg9tIiVOXm+
659M1JRYeh/r2JHzL5NJHB7aIHL+fGD0kLZkukBuF3sXvwtfhib2XjGbinrCMNsA+vi169HesMvIjG
66YTnGltD/gaBERNtYUELXfqQGdDtuaPD/0YJqTK/CmQL24PYmc3fi8pL6e3LytKarhomyJ6XduBE3
6748/y7iTjEZwtGEC7+CsnV/YyTc3QqXg2M1zDH3gfL2IrVgka8UJVjonsX4kpovz3Cvq0Gh/jM1wl
68WsGkNvQfk5N3lPI0h9ST0qxsXNyAHbgg59BaXNLMVk5uZnOXoGc9oj9uMkCb8rhC9FciW+9tw+Z6
69A7x2rODZZV5ySC/5ZgGYgq7ceGM5d4bYbGb3spy8rk3956I7k3diWZt6BqEMbSJKMX/u7myyrh20
704rb5o24ZurYkJ6/AYk1OQAVsyz77U3Ei1Zm/RRkeLrKmD714XPQyor9elKgvBf3iwmJkZp+4hVot
71LmTq6NY+FuJ+wVTgMUGnFuMcnCB6+R58jy8Fd10lTo9LCvqSA7pVHP3q6M+M5EtyscHlXxa7RT+u
72Z2kts5nPoHm4taSdpSJBHs7GG3CTuC6cjKMEX+3N7NcxppGy1ID2a37cm4i7xE6XRb5v1jSnYqPE
731dlyUTVlsUxcejwgXk4ErdqWPUVMxW2YUJxoFdDxwuk+g3ttLfvcNHHp2o1j031viRGCsPcayg1r
74ogRnisxNuYMdDq7GlXhXMIgPRYvpz3yZIIK+QLSKhhnaijZVjf/ij3R9IqCdEl/gVV9oHGzoNEzm
75cuhHuorxDy1c2Kp4SUJrAAAAAElFTkSuQmCC
76"
77 id="image10"
78 x="0"
79 y="0" />
80</svg>
081
=== added file 'tests/unit/bbc/images/logo.png'
1Binary files tests/unit/bbc/images/logo.png 1970-01-01 00:00:00 +0000 and tests/unit/bbc/images/logo.png 2015-05-20 13:57:15 +0000 differ82Binary files tests/unit/bbc/images/logo.png 1970-01-01 00:00:00 +0000 and tests/unit/bbc/images/logo.png 2015-05-20 13:57:15 +0000 differ
=== added file 'tests/unit/bbc/images/logo.svg'
--- tests/unit/bbc/images/logo.svg 1970-01-01 00:00:00 +0000
+++ tests/unit/bbc/images/logo.svg 2015-05-20 13:57:15 +0000
@@ -0,0 +1,60 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!-- Created with Inkscape (http://www.inkscape.org/) -->
3
4<svg
5 xmlns:dc="http://purl.org/dc/elements/1.1/"
6 xmlns:cc="http://creativecommons.org/ns#"
7 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
8 xmlns:svg="http://www.w3.org/2000/svg"
9 xmlns="http://www.w3.org/2000/svg"
10 xmlns:xlink="http://www.w3.org/1999/xlink"
11 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
12 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
13 id="svg2"
14 version="1.1"
15 inkscape:version="0.48.4 r9939"
16 width="84"
17 height="84"
18 sodipodi:docname="logo.svg">
19 <metadata
20 id="metadata8">
21 <rdf:RDF>
22 <cc:Work
23 rdf:about="">
24 <dc:format>image/svg+xml</dc:format>
25 <dc:type
26 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
27 <dc:title />
28 </cc:Work>
29 </rdf:RDF>
30 </metadata>
31 <defs
32 id="defs6" />
33 <sodipodi:namedview
34 pagecolor="#ffffff"
35 bordercolor="#666666"
36 borderopacity="1"
37 objecttolerance="10"
38 gridtolerance="10"
39 guidetolerance="10"
40 inkscape:pageopacity="0"
41 inkscape:pageshadow="2"
42 inkscape:window-width="915"
43 inkscape:window-height="728"
44 id="namedview4"
45 showgrid="false"
46 inkscape:zoom="3.8571429"
47 inkscape:cx="42"
48 inkscape:cy="12"
49 inkscape:window-x="49"
50 inkscape:window-y="24"
51 inkscape:window-maximized="0"
52 inkscape:current-layer="svg2" />
53 <image
54 width="84"
55 height="24"
56 xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFQAAAAYCAYAAABk8drWAAAABHNCSVQICAgIfAhkiAAABA1JREFU WIXt2VuIlVUUB/DfNJppimZ2May0LEQr0ekqlljEdKUL9RBdHiNCCKQSgh6yDKKHrJ4KglIyygJ7 qSgpuotW9pKlINloU3Shm6alM6eH9R3nm2/OOe0534eQ+YePWXv2Pmuts/Za6/vvfTq6urpqDgw6 cvJBa/OwA2Hk/4RDAa0YI1rM/YjnRakUS2cczsAcjKrQn71YgV/RWbA5CqfifIyv0GYR32A9NuIL /IZJOBOzMBvTDY7JfnS06KGfY67WvWcensGMBEdT+tlOzMT2FnpOwhO4piKbdXyLB8WG7m6xbiQu xCJcV5xMLfkOkc0jCk5+hIuxKVFPip28/rrNvJ89uBavVGQT1ojMe8pAMDtxHE7O/tYrZi/exlIN Nik1oKfgU1ECn+BpHJ/NfScypmqMxhv4SpTfGpyXm78Puyqw8xKux8/ZeCLuFsmyRSTLFmzAk6Ll QH8jZa16aB5HiFKsr5+LMbglG78ndm5kor4UdOJ0nJiNzxJ9e7YI5BZsznxpF5txh4FMuxTPYXKD tXOyZxHewWvYp/CdUwPaqP9My8nFUq0CtQZ2j8aRqslMeBS/ZPJ8vCoq49+wMHuGYDg9tIiVOXm+ 9M1JRYeh/r2JHzL5NJHB7aIHL+fGD0kLZkukBuF3sXvwtfhib2XjGbinrCMNsA+vi169HesMvIjG YTnGltD/gaBERNtYUELXfqQGdDtuaPD/0YJqTK/CmQL24PYmc3fi8pL6e3LytKarhomyJ6XduBE3 48/y7iTjEZwtGEC7+CsnV/YyTc3QqXg2M1zDH3gfL2IrVgka8UJVjonsX4kpovz3Cvq0Gh/jM1wl WsGkNvQfk5N3lPI0h9ST0qxsXNyAHbgg59BaXNLMVk5uZnOXoGc9oj9uMkCb8rhC9FciW+9tw+Z6 A7x2rODZZV5ySC/5ZgGYgq7ceGM5d4bYbGb3spy8rk3956I7k3diWZt6BqEMbSJKMX/u7myyrh20 4rb5o24ZurYkJ6/AYk1OQAVsyz77U3Ei1Zm/RRkeLrKmD714XPQyor9elKgvBf3iwmJkZp+4hVot LmTq6NY+FuJ+wVTgMUGnFuMcnCB6+R58jy8Fd10lTo9LCvqSA7pVHP3q6M+M5EtyscHlXxa7RT+u Z2kts5nPoHm4taSdpSJBHs7GG3CTuC6cjKMEX+3N7NcxppGy1ID2a37cm4i7xE6XRb5v1jSnYqPE 1dlyUTVlsUxcejwgXk4ErdqWPUVMxW2YUJxoFdDxwuk+g3ttLfvcNHHp2o1j031viRGCsPcayg1r ogRnisxNuYMdDq7GlXhXMIgPRYvpz3yZIIK+QLSKhhnaijZVjf/ij3R9IqCdEl/gVV9oHGzoNEzm cuhHuorxDy1c2Kp4SUJrAAAAAElFTkSuQmCC "
57 id="image10"
58 x="0.25925925"
59 y="29.148148" />
60</svg>
061
=== added file 'tests/unit/bbc/images/scope-card.png'
1Binary files tests/unit/bbc/images/scope-card.png 1970-01-01 00:00:00 +0000 and tests/unit/bbc/images/scope-card.png 2015-05-20 13:57:15 +0000 differ62Binary files tests/unit/bbc/images/scope-card.png 1970-01-01 00:00:00 +0000 and tests/unit/bbc/images/scope-card.png 2015-05-20 13:57:15 +0000 differ
=== added file 'tests/unit/bbc/logo.png'
2Binary files tests/unit/bbc/logo.png 1970-01-01 00:00:00 +0000 and tests/unit/bbc/logo.png 2015-05-20 13:57:15 +0000 differ63Binary files tests/unit/bbc/logo.png 1970-01-01 00:00:00 +0000 and tests/unit/bbc/logo.png 2015-05-20 13:57:15 +0000 differ
=== added file 'tests/unit/bbc/rss.ssweeny_rss.ini.in'
--- tests/unit/bbc/rss.ssweeny_rss.ini.in 1970-01-01 00:00:00 +0000
+++ tests/unit/bbc/rss.ssweeny_rss.ini.in 2015-05-20 13:57:15 +0000
@@ -0,0 +1,11 @@
1[ScopeConfig]
2_DisplayName=BBC
3_Description=BBC
4Art=screenshot.png
5Author=Scott Sweeny
6Icon=icon.png
7
8[Appearance]
9PageHeader.Logo=logo.png
10PageHeader.Background=color:///#e9e7e8
11PageHeader.DividerColor=#ffeb00
012
=== added file 'tests/unit/bbc/screenshot.png'
1Binary files tests/unit/bbc/screenshot.png 1970-01-01 00:00:00 +0000 and tests/unit/bbc/screenshot.png 2015-05-20 13:57:15 +0000 differ13Binary files tests/unit/bbc/screenshot.png 1970-01-01 00:00:00 +0000 and tests/unit/bbc/screenshot.png 2015-05-20 13:57:15 +0000 differ
=== added directory 'tests/unit/cnet'
=== added file 'tests/unit/cnet/CMakeLists.txt'
--- tests/unit/cnet/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ tests/unit/cnet/CMakeLists.txt 2015-05-20 13:57:15 +0000
@@ -0,0 +1,36 @@
1# Put the ini file in the build directory next to the scope
2# .so file so test tools can find both easily.
3#this is for launching on desktop with unity-scope-tool from src dir
4configure_file(
5 "rss-scope.ini.in.in"
6 "${CMAKE_BINARY_DIR}/src/rss-scope.ini"
7)
8#this is the basis for localization
9configure_file(
10 "rss-scope.ini.in.in"
11 "${CMAKE_SOURCE_DIR}/data/rss-scope.ini.in"
12)
13
14file(GLOB INIS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.ini.in)
15foreach(INI ${INIS})
16 string(REPLACE ".ini.in" ".ini" INIFINAL ${INI})
17 exec_program("intltool-merge -d -u ${CMAKE_SOURCE_DIR}/po/ ${CMAKE_CURRENT_SOURCE_DIR}/${INI} ${CMAKE_CURRENT_BINARY_DIR}/${INIFINAL}")
18endforeach(INI)
19
20INSTALL(
21 FILES "${CMAKE_CURRENT_BINARY_DIR}/rss-scope.ini"
22 DESTINATION ${INI_INSTALLDIR}
23 RENAME ${SO_NAME}.ini
24)
25INSTALL(
26 FILES departments.json
27 DESTINATION ${SCOPE_INSTALLDIR}
28)
29INSTALL(
30 DIRECTORY "renderer"
31 DESTINATION ${SCOPE_INSTALLDIR}
32)
33INSTALL(
34 DIRECTORY "images"
35 DESTINATION ${SCOPE_INSTALLDIR}
36)
037
=== added directory 'tests/unit/cnet/cache'
=== added file 'tests/unit/cnet/cache/.cheat-click'
--- tests/unit/cnet/cache/.cheat-click 1970-01-01 00:00:00 +0000
+++ tests/unit/cnet/cache/.cheat-click 2015-05-20 13:57:15 +0000
@@ -0,0 +1,1 @@
1This file will force click to include the empty cache directory in the click package.
02
=== added file 'tests/unit/cnet/feeds.json'
--- tests/unit/cnet/feeds.json 1970-01-01 00:00:00 +0000
+++ tests/unit/cnet/feeds.json 2015-05-20 13:57:15 +0000
@@ -0,0 +1,50 @@
1[
2 {
3 "label": "All",
4 "id": "http://127.0.0.1:9999/cnet/rss/all/index.xml"
5 },
6 {
7 "label": "News",
8 "id": "http://127.0.0.1:9999/cnet/rss/news/"
9 },
10 {
11 "label": "Reviews",
12 "id": "http://127.0.0.1:9999/cnet/rss/reviews/"
13 },
14 {
15 "label": "Video",
16 "id": "http://127.0.0.1:9999/cnet/rss/video/"
17 },
18 {
19 "label": "How To",
20 "id": "http://127.0.0.1:9999/cnet/rss/how-to/"
21 },
22 {
23 "label": "Deals",
24 "id": "http://127.0.0.1:9999/cnet/rss/deals/"
25 },
26 {
27 "label": "Crave",
28 "id": "http://127.0.0.1:9999/cnet/rss/crave/"
29 },
30 {
31 "label": "Car Tech",
32 "id": "http://127.0.0.1:9999/cnet/rss/car-tech/"
33 },
34 {
35 "label": "Android Update",
36 "id": "http://127.0.0.1:9999/cnet/rss/android-update/"
37 },
38 {
39 "label": "Gaming",
40 "id": "http://127.0.0.1:9999/cnet/rss/gaming/"
41 },
42 {
43 "label": "Cheapskate",
44 "id": "http://127.0.0.1:9999/cnet/rss/cheapskate/"
45 },
46 {
47 "label": "Podcasts",
48 "id": "http://127.0.0.1:9999/cnet/rss/cnet-podcasts/"
49 }
50]
051
=== added file 'tests/unit/cnet/icon.svg'
--- tests/unit/cnet/icon.svg 1970-01-01 00:00:00 +0000
+++ tests/unit/cnet/icon.svg 2015-05-20 13:57:15 +0000
@@ -0,0 +1,92 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!-- Created with Inkscape (http://www.inkscape.org/) -->
3<svg
4 xmlns:svg="http://www.w3.org/2000/svg"
5 xmlns="http://www.w3.org/2000/svg"
6 version="1.0"
7 width="544.00006"
8 height="544"
9 id="svg2">
10 <defs
11 id="defs4" />
12 <g
13 transform="translate(-6.4712476,3.0971002)"
14 id="layer1">
15 <g
16 transform="matrix(0.8880597,0,0,0.8880597,0.7243933,-0.3466903)"
17 id="g3208">
18 <g
19 transform="matrix(34.669279,0,0,-34.669276,312.75001,137.48351)"
20 id="g17052">
21 <path
22 d="M 0,0 C -1.891,0 -3.424,-1.533 -3.424,-3.425 C -3.424,-5.316 -1.891,-6.849 0,-6.849 C 1.891,-6.849 3.424,-5.316 3.424,-3.425 C 3.424,-1.533 1.891,0 0,0"
23 id="path17054"
24 style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" />
25 </g>
26 <g
27 transform="matrix(34.669279,0,0,-34.669276,207.7853,422.93993)"
28 id="g17056">
29 <path
30 d="M 0,0 L -0.005,0 L -0.005,-0.757 C -0.005,-0.85 -0.038,-0.935 -0.098,-0.996 C -0.155,-1.056 -0.232,-1.089 -0.314,-1.089 C -0.396,-1.089 -0.473,-1.056 -0.53,-0.996 C -0.59,-0.935 -0.622,-0.85 -0.622,-0.757 L -0.622,0 L -0.869,0 L -0.869,-0.757 C -0.869,-0.922 -0.815,-1.065 -0.711,-1.169 C -0.61,-1.27 -0.469,-1.325 -0.314,-1.325 C -0.159,-1.325 -0.018,-1.27 0.083,-1.169 C 0.187,-1.065 0.242,-0.922 0.242,-0.757 L 0.242,0 L 0.237,0"
31 id="path17058"
32 style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" />
33 </g>
34 <g
35 transform="matrix(34.669279,0,0,-34.669276,280.39317,456.46858)"
36 id="g17060">
37 <path
38 d="M 0,0 C -0.075,-0.079 -0.181,-0.122 -0.298,-0.122 C -0.416,-0.122 -0.522,-0.079 -0.597,0 C -0.673,0.079 -0.714,0.192 -0.714,0.317 C -0.714,0.442 -0.673,0.556 -0.597,0.635 C -0.522,0.714 -0.416,0.757 -0.298,0.757 C -0.181,0.757 -0.075,0.714 0,0.635 C 0.076,0.556 0.117,0.442 0.117,0.317 C 0.117,0.192 0.076,0.079 0,0 M 0.173,0.806 C 0.048,0.927 -0.121,0.994 -0.298,0.994 C -0.477,0.994 -0.645,0.927 -0.77,0.806 C -0.901,0.68 -0.972,0.507 -0.972,0.317 C -0.972,0.128 -0.901,-0.045 -0.77,-0.171 C -0.645,-0.292 -0.477,-0.358 -0.298,-0.358 C -0.121,-0.358 0.048,-0.292 0.173,-0.171 C 0.304,-0.045 0.375,0.128 0.375,0.317 C 0.375,0.507 0.304,0.68 0.173,0.806"
39 id="path17062"
40 style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" />
41 </g>
42 <g
43 transform="matrix(34.669279,0,0,-34.669276,319.16729,422.00733)"
44 id="g17064">
45 <path
46 d="M 0,0 C -0.155,0 -0.296,-0.055 -0.397,-0.157 C -0.5,-0.261 -0.556,-0.404 -0.556,-0.569 L -0.556,-1.326 L -0.309,-1.326 L -0.309,-0.569 C -0.309,-0.476 -0.276,-0.391 -0.217,-0.329 C -0.159,-0.269 -0.082,-0.237 0,-0.237 C 0.082,-0.237 0.159,-0.269 0.216,-0.329 C 0.276,-0.391 0.309,-0.476 0.309,-0.569 L 0.309,-1.326 L 0.556,-1.326 L 0.556,-0.569 C 0.556,-0.404 0.501,-0.261 0.397,-0.157 C 0.296,-0.055 0.155,0 0,0"
47 id="path17066"
48 style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" />
49 </g>
50 <g
51 transform="matrix(34.669279,0,0,-34.669276,447.51643,422.93993)"
52 id="g17068">
53 <path
54 d="M 0,0 L -0.005,0 L -0.005,-0.827 C -0.005,-0.986 -0.094,-1.089 -0.231,-1.089 C -0.395,-1.089 -0.478,-0.988 -0.478,-0.789 L -0.478,0 L -0.725,0 L -0.725,-0.789 C -0.725,-0.988 -0.808,-1.089 -0.972,-1.089 C -1.109,-1.089 -1.197,-0.986 -1.197,-0.827 L -1.197,0 L -1.444,0 L -1.444,-0.88 C -1.444,-1.13 -1.239,-1.325 -0.977,-1.325 C -0.819,-1.325 -0.683,-1.26 -0.601,-1.147 C -0.519,-1.26 -0.383,-1.325 -0.225,-1.325 C 0.036,-1.325 0.242,-1.13 0.242,-0.88 L 0.242,0 L 0.237,0"
55 id="path17070"
56 style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" />
57 </g>
58 <g
59 transform="matrix(34.669279,0,0,-34.669276,482.0401,440.7114)"
60 id="g17072">
61 <path
62 d="M 0,0 C -0.158,0.044 -0.294,0.082 -0.294,0.169 C -0.289,0.242 -0.265,0.277 -0.146,0.277 L 0.455,0.277 L 0.455,0.513 L -0.106,0.513 C -0.393,0.513 -0.552,0.387 -0.552,0.158 C -0.552,0.042 -0.497,-0.049 -0.384,-0.119 C -0.287,-0.179 -0.159,-0.216 -0.046,-0.249 C 0.119,-0.296 0.262,-0.337 0.262,-0.432 C 0.262,-0.514 0.216,-0.55 0.114,-0.55 L -0.552,-0.55 L -0.552,-0.787 L 0.114,-0.787 C 0.232,-0.787 0.332,-0.756 0.403,-0.697 C 0.479,-0.634 0.52,-0.538 0.52,-0.422 C 0.52,-0.145 0.232,-0.065 0,0"
63 id="path17074"
64 style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" />
65 </g>
66 <g
67 transform="matrix(34.669279,0,0,-34.669276,223.62569,440.00761)"
68 id="g17076">
69 <path
70 d="M 0,0 L 0,-0.796 L 0.23,-0.796 L 0.23,0 C 0.23,0.147 0.275,0.315 0.627,0.315 L 0.633,0.315 L 0.633,0.545 L 0.627,0.545 C 0.082,0.545 0,0.203 0,0"
71 id="path17078"
72 style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" />
73 </g>
74 <g
75 transform="matrix(34.669279,0,0,-34.669276,162.68056,452.232)"
76 id="g17080">
77 <path
78 d="M 0,0 L -0.005,0.002 L -0.007,-0.003 C -0.043,-0.07 -0.096,-0.129 -0.163,-0.171 C -0.371,-0.303 -0.648,-0.24 -0.779,-0.032 C -0.843,0.068 -0.864,0.188 -0.837,0.304 C -0.811,0.421 -0.741,0.52 -0.641,0.584 C -0.492,0.677 -0.303,0.675 -0.157,0.579 L -0.551,0.255 L -0.556,0.252 L -0.552,0.248 L -0.417,0.08 L -0.414,0.075 L -0.41,0.079 L 0.169,0.554 L 0.172,0.557 L 0.17,0.561 L 0.166,0.566 C 0.07,0.717 -0.079,0.822 -0.255,0.861 C -0.43,0.901 -0.61,0.87 -0.761,0.774 C -0.912,0.679 -1.018,0.53 -1.057,0.355 C -1.097,0.179 -1.066,-0.001 -0.97,-0.153 C -0.772,-0.466 -0.356,-0.56 -0.043,-0.362 C 0.056,-0.299 0.137,-0.212 0.192,-0.108 L 0.195,-0.103 L 0.19,-0.1"
79 id="path17082"
80 style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" />
81 </g>
82 <g
83 transform="matrix(34.669279,0,0,-34.669276,381.92215,452.232)"
84 id="g17084">
85 <path
86 d="M 0,0 L -0.005,0.002 L -0.008,-0.003 C -0.043,-0.07 -0.097,-0.129 -0.163,-0.171 C -0.371,-0.303 -0.648,-0.24 -0.78,-0.032 C -0.843,0.068 -0.864,0.188 -0.838,0.305 C -0.811,0.421 -0.741,0.52 -0.641,0.584 C -0.493,0.677 -0.304,0.675 -0.157,0.579 L -0.552,0.255 L -0.556,0.252 L -0.552,0.248 L -0.417,0.08 L -0.414,0.075 L -0.409,0.079 L 0.168,0.554 L 0.173,0.557 L 0.169,0.561 L 0.166,0.566 L 0.166,0.566 C -0.032,0.879 -0.448,0.972 -0.761,0.774 C -0.913,0.679 -1.018,0.53 -1.057,0.355 C -1.097,0.179 -1.066,-0.001 -0.971,-0.153 C -0.772,-0.466 -0.356,-0.56 -0.043,-0.362 C 0.056,-0.299 0.137,-0.212 0.192,-0.108 L 0.195,-0.103 L 0.19,-0.1"
87 id="path17086"
88 style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" />
89 </g>
90 </g>
91 </g>
92</svg>
093
=== added directory 'tests/unit/cnet/images'
=== added file 'tests/unit/cnet/images/card.png'
1Binary files tests/unit/cnet/images/card.png 1970-01-01 00:00:00 +0000 and tests/unit/cnet/images/card.png 2015-05-20 13:57:15 +0000 differ94Binary files tests/unit/cnet/images/card.png 1970-01-01 00:00:00 +0000 and tests/unit/cnet/images/card.png 2015-05-20 13:57:15 +0000 differ
=== added file 'tests/unit/cnet/images/default.png'
2Binary files tests/unit/cnet/images/default.png 1970-01-01 00:00:00 +0000 and tests/unit/cnet/images/default.png 2015-05-20 13:57:15 +0000 differ95Binary files tests/unit/cnet/images/default.png 1970-01-01 00:00:00 +0000 and tests/unit/cnet/images/default.png 2015-05-20 13:57:15 +0000 differ
=== added file 'tests/unit/cnet/images/default.svg'
--- tests/unit/cnet/images/default.svg 1970-01-01 00:00:00 +0000
+++ tests/unit/cnet/images/default.svg 2015-05-20 13:57:15 +0000
@@ -0,0 +1,322 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!-- Created with Inkscape (http://www.inkscape.org/) -->
3
4<svg
5 xmlns:dc="http://purl.org/dc/elements/1.1/"
6 xmlns:cc="http://creativecommons.org/ns#"
7 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
8 xmlns:svg="http://www.w3.org/2000/svg"
9 xmlns="http://www.w3.org/2000/svg"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12 width="720"
13 height="330"
14 id="svg2"
15 sodipodi:version="0.32"
16 inkscape:version="0.48.4 r9939"
17 version="1.0"
18 sodipodi:docname="default.svg.old"
19 inkscape:output_extension="org.inkscape.output.svg.inkscape">
20 <defs
21 id="defs4" />
22 <sodipodi:namedview
23 id="base"
24 pagecolor="#ffffff"
25 bordercolor="#666666"
26 borderopacity="1.0"
27 gridtolerance="10000"
28 guidetolerance="10"
29 objecttolerance="10"
30 inkscape:pageopacity="0.0"
31 inkscape:pageshadow="2"
32 inkscape:zoom="0.88003809"
33 inkscape:cx="490.40724"
34 inkscape:cy="124.4655"
35 inkscape:document-units="px"
36 inkscape:current-layer="layer1"
37 height="24px"
38 width="24px"
39 showgrid="true"
40 inkscape:window-width="1366"
41 inkscape:window-height="744"
42 inkscape:window-x="0"
43 inkscape:window-y="24"
44 inkscape:snap-nodes="true"
45 inkscape:window-maximized="1"
46 fit-margin-top="0"
47 fit-margin-left="0"
48 fit-margin-right="0"
49 fit-margin-bottom="0" />
50 <metadata
51 id="metadata7">
52 <rdf:RDF>
53 <cc:Work
54 rdf:about="">
55 <dc:format>image/svg+xml</dc:format>
56 <dc:type
57 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
58 <dc:title></dc:title>
59 </cc:Work>
60 </rdf:RDF>
61 </metadata>
62 <g
63 inkscape:label="Layer 1"
64 inkscape:groupmode="layer"
65 id="layer1"
66 transform="translate(-5.7571953,-706.0344)">
67 <g
68 id="g15405"
69 clip-path="url(#id335)"
70 transform="matrix(1,0,0,-1,-328.30292,933.75171)">
71 <g
72 id="g15407"
73 transform="matrix(0.0384521,0,0,-0.0384521,58.949158,55.939194)">
74 <path
75 id="path15409"
76 d="m 0,0 -11.3,0 0,-11.5 -5,0 0,28.801 5,0 0,-12.301 0.5,-0.699 10.1,0 0.7,0.5 0,12.5 5,0 0,-28.801 -5,0 L 0,0 z"
77 style="fill:#1c4e9d;fill-rule:nonzero;stroke:none"
78 inkscape:connector-curvature="0" />
79 </g>
80 <g
81 id="g15411"
82 transform="matrix(0.0384521,0,0,-0.0384521,60.075806,56.381393)">
83 <path
84 id="path15413"
85 d="m 0,0 -10.6,28.801 5.1,0 2.4,-6.5 11.5,0 2.4,6.5 L 16.1,28.5 5.5,0 0,0 z M -1,17.7 C -0.1,14 1.1,9.801 2.6,6 4.3,9.5 5.2,13.7 6.5,17.5 L -1,17.7"
86 style="fill:#1c4e9d;fill-rule:nonzero;stroke:none"
87 inkscape:connector-curvature="0" />
88 </g>
89 <g
90 id="g15415"
91 transform="matrix(0.0384521,0,0,-0.0384521,61.883057,55.550842)">
92 <path
93 id="path15417"
94 d="m 0,0 c -4.3,-6.7 -6.8,-14.6 -10.8,-21.6 l -6,0 0,28.801 4.6,0 0.2,-21.601 c 3.8,6.9 7.3,14.3 10.6,21.601 l 6.201,0 0,-28.801 -4.5,0 L 0,0"
95 style="fill:#1c4e9d;fill-rule:nonzero;stroke:none"
96 inkscape:connector-curvature="0" />
97 </g>
98 <g
99 id="g15419"
100 transform="matrix(0.0384521,0,0,-0.0384521,63.478821,55.550842)">
101 <path
102 id="path15421"
103 d="m 0,0 c -3.8,-7.1 -6.699,-14.5 -10.5,-21.6 l -6.3,0 0,28.801 4.8,0 0.301,-21.601 c 3.599,6.9 7.099,14.3 10.5,21.601 l 6.299,0 0,-28.801 -4.799,0.2 L 0,0"
104 style="fill:#1c4e9d;fill-rule:nonzero;stroke:none"
105 inkscape:connector-curvature="0" />
106 </g>
107 <g
108 id="g15423"
109 transform="matrix(0.0384521,0,0,-0.0384521,65.139938,56.223755)">
110 <path
111 id="path15425"
112 d="m 0,0 -0.2,-4.1 -17.8,0 0,28.801 18,0 0,-4.301 -12.899,-0.3 0.199,-7.7 11.301,0 0,-3.8 -11.5,-0.5 L -12.7,0.201 0,0 z"
113 style="fill:#1c4e9d;fill-rule:nonzero;stroke:none"
114 inkscape:connector-curvature="0" />
115 </g>
116 <g
117 id="g15427"
118 transform="matrix(0.0384521,0,0,-0.0384521,66.06279,56.381393)">
119 <path
120 id="path15429"
121 d="m 0,0 -4.8,0 0,28.801 16.3,0 0,-4.301 -11,0 L 0,0 z"
122 style="fill:#1c4e9d;fill-rule:nonzero;stroke:none"
123 inkscape:connector-curvature="0" />
124 </g>
125 </g>
126 <g
127 id="g35751"
128 clip-path="url(#id554)"
129 transform="matrix(1,0,0,-1,-328.30292,933.75171)">
130 <g
131 id="g35753"
132 transform="matrix(0.0384521,0,0,-0.0384521,58.949158,55.939194)">
133 <path
134 id="path35755"
135 d="m 0,0 -11.3,0 0,-11.5 -5,0 0,28.801 5,0 0,-12.301 0.5,-0.699 10.1,0 0.7,0.5 0,12.5 5,0 0,-28.801 -5,0 L 0,0 z"
136 style="fill:#1c4e9d;fill-rule:nonzero;stroke:none"
137 inkscape:connector-curvature="0" />
138 </g>
139 <g
140 id="g35757"
141 transform="matrix(0.0384521,0,0,-0.0384521,60.075806,56.381393)">
142 <path
143 id="path35759"
144 d="m 0,0 -10.6,28.801 5.1,0 2.4,-6.5 11.5,0 2.4,6.5 L 16.1,28.5 5.5,0 0,0 z M -1,17.7 C -0.1,14 1.1,9.801 2.6,6 4.3,9.5 5.2,13.7 6.5,17.5 L -1,17.7"
145 style="fill:#1c4e9d;fill-rule:nonzero;stroke:none"
146 inkscape:connector-curvature="0" />
147 </g>
148 <g
149 id="g35761"
150 transform="matrix(0.0384521,0,0,-0.0384521,61.883057,55.550842)">
151 <path
152 id="path35763"
153 d="m 0,0 c -4.3,-6.7 -6.8,-14.6 -10.8,-21.6 l -6,0 0,28.801 4.6,0 0.2,-21.601 c 3.8,6.9 7.3,14.3 10.6,21.601 l 6.201,0 0,-28.801 -4.5,0 L 0,0"
154 style="fill:#1c4e9d;fill-rule:nonzero;stroke:none"
155 inkscape:connector-curvature="0" />
156 </g>
157 <g
158 id="g35765"
159 transform="matrix(0.0384521,0,0,-0.0384521,63.478821,55.550842)">
160 <path
161 id="path35767"
162 d="m 0,0 c -3.8,-7.1 -6.699,-14.5 -10.5,-21.6 l -6.3,0 0,28.801 4.8,0 0.301,-21.601 c 3.599,6.9 7.099,14.3 10.5,21.601 l 6.299,0 0,-28.801 -4.799,0.2 L 0,0"
163 style="fill:#1c4e9d;fill-rule:nonzero;stroke:none"
164 inkscape:connector-curvature="0" />
165 </g>
166 <g
167 id="g35769"
168 transform="matrix(0.0384521,0,0,-0.0384521,65.139938,56.223755)">
169 <path
170 id="path35771"
171 d="m 0,0 -0.2,-4.1 -17.8,0 0,28.801 18,0 0,-4.301 -12.899,-0.3 0.199,-7.7 11.301,0 0,-3.8 -11.5,-0.5 L -12.7,0.201 0,0 z"
172 style="fill:#1c4e9d;fill-rule:nonzero;stroke:none"
173 inkscape:connector-curvature="0" />
174 </g>
175 <g
176 id="g35773"
177 transform="matrix(0.0384521,0,0,-0.0384521,66.06279,56.381393)">
178 <path
179 id="path35775"
180 d="m 0,0 -4.8,0 0,28.801 16.3,0 0,-4.301 -11,0 L 0,0 z"
181 style="fill:#1c4e9d;fill-rule:nonzero;stroke:none"
182 inkscape:connector-curvature="0" />
183 </g>
184 </g>
185 <path
186 id="path52181"
187 d="m 5.7571953,706.0344 720.0000047,0 0,330 -720.0000047,0 0,-330 z"
188 style="fill:#b6b5b5;fill-rule:nonzero;stroke:none"
189 inkscape:connector-curvature="0" />
190 <g
191 transform="matrix(2.1166696,0,0,2.2148216,250.77235,1223.5571)"
192 id="g52187">
193 <path
194 inkscape:connector-curvature="0"
195 style="fill:#ffffff;fill-rule:nonzero;stroke:none"
196 d="m 0,-170.06272 -0.101,0 0,0.1 0,13.828 c 0,1.705 -0.601,3.267 -1.695,4.404 -1.058,1.1 -2.476,1.707 -3.985,1.707 -1.509,0 -2.922,-0.607 -3.979,-1.707 -1.092,-1.135 -1.691,-2.699 -1.691,-4.404 l 0,-13.828 0,-0.1 -0.1,0 -4.345,0 -0.102,0 0,0.1 0,13.828 c 0,3.039 1.011,5.662 2.925,7.582 1.85,1.859 4.441,2.883 7.292,2.883 2.856,0 5.45,-1.024 7.305,-2.883 1.911,-1.92 2.923,-4.541 2.923,-7.582 l 0,-13.828 0,-0.1 -0.098,0 -4.349,0 z"
197 id="path52189" />
198 </g>
199 <g
200 transform="matrix(2.1166696,0,0,2.2148216,332.31519,1262.9618)"
201 id="g52191">
202 <path
203 inkscape:connector-curvature="0"
204 style="fill:#ffffff;fill-rule:nonzero;stroke:none"
205 d="m 0,-170.06272 c -1.383,1.449 -3.334,2.248 -5.489,2.248 -2.156,0 -4.106,-0.799 -5.489,-2.248 -1.392,-1.463 -2.159,-3.533 -2.159,-5.832 0,-2.307 0.767,-4.385 2.159,-5.848 1.382,-1.453 3.331,-2.252 5.489,-2.252 2.155,0 4.106,0.799 5.489,2.252 1.396,1.465 2.162,3.541 2.162,5.848 0,2.299 -0.766,4.369 -2.162,5.832 m 3.186,-14.822 c -2.312,-2.23501 -5.395,-3.46301 -8.675,-3.46301 -3.285,0 -6.368,1.228 -8.682,3.46301 -2.394,2.312 -3.712,5.506 -3.712,8.99 0,3.481 1.318,6.668 3.712,8.979 2.313,2.228 5.397,3.455 8.682,3.455 3.28,0 6.363,-1.227 8.675,-3.455 2.401,-2.311 3.719,-5.498 3.719,-8.979 0,-3.482 -1.318,-6.676 -3.719,-8.99"
206 id="path52193" />
207 </g>
208 <g
209 transform="matrix(2.1166696,0,0,2.2148216,375.87691,1222.4616)"
210 id="g52195">
211 <path
212 inkscape:connector-curvature="0"
213 style="fill:#ffffff;fill-rule:nonzero;stroke:none"
214 d="m 0,-170.06272 c -2.854,0 -5.448,1.023 -7.299,2.883 -1.914,1.92 -2.924,4.545 -2.924,7.592 l 0,13.828 0,0.099 0.1,0 4.343,0 0.1,0 0,-0.099 0,-13.828 c 0,-1.709 0.603,-3.278 1.696,-4.413 1.061,-1.103 2.476,-1.709 3.984,-1.709 1.508,0 2.925,0.606 3.982,1.709 1.094,1.135 1.693,2.704 1.693,4.413 l 0,13.828 0,0.099 0.1,0 4.355,0 0.101,0 0,-0.099 0,-13.828 c 0,-3.043 -1.012,-5.668 -2.926,-7.592 -1.857,-1.862 -4.45,-2.883 -7.305,-2.883"
215 id="path52197" />
216 </g>
217 <g
218 transform="matrix(2.1166696,0,0,2.2148216,520.04351,1223.5571)"
219 id="g52199">
220 <path
221 inkscape:connector-curvature="0"
222 style="fill:#ffffff;fill-rule:nonzero;stroke:none"
223 d="m 0,-170.06272 -0.102,0 0,0.1 0,15.115 c 0,2.93 -1.627,4.824 -4.146,4.824 -3.014,0 -4.543,-1.857 -4.543,-5.519 l 0,-14.42 0,-0.1 -0.102,0 -4.339,0 -0.1,0 0,0.1 0,14.42 c 0,3.662 -1.529,5.519 -4.547,5.519 -2.517,0 -4.146,-1.894 -4.146,-4.824 l 0,-15.115 0,-0.1 -0.098,0 -4.35,0 -0.097,0 0,0.1 0,16.09 c 0,4.599 3.777,8.203 8.599,8.203 2.889,0 5.398,-1.202 6.916,-3.293 1.502,2.091 4.008,3.293 6.909,3.293 4.816,0 8.587,-3.604 8.587,-8.203 l 0,-16.09 0,-0.1 -0.096,0 -4.345,0 z"
224 id="path52201" />
225 </g>
226 <g
227 transform="matrix(2.1166696,0,0,2.2148216,558.82208,1244.4554)"
228 id="g52203">
229 <path
230 inkscape:connector-curvature="0"
231 style="fill:#ffffff;fill-rule:nonzero;stroke:none"
232 d="m 0,-170.06272 c -2.902,-0.809 -5.408,-1.51 -5.408,-3.108 0.095,-1.344 0.525,-1.984 2.713,-1.984 l 10.966,0 0.098,0 0,-0.1 0,-4.144 0,-0.1 -0.098,0 -10.222,0 c -5.289,0 -8.201,2.315 -8.201,6.52 0,2.15 1.007,3.82 3.08,5.105 1.793,1.111 4.144,1.785 6.224,2.383 3.036,0.871 5.661,1.625 5.661,3.383 0,1.496 -0.838,2.164 -2.713,2.164 l -12.153,0 -0.099,0 0,0.099 0,4.155 0,0.099 0.099,0 12.153,0 c 2.175,0 4.013,-0.57 5.31,-1.65 1.403,-1.166 2.141,-2.916 2.141,-5.065 0,-5.091 -5.295,-6.57 -9.551,-7.757"
233 id="path52205" />
234 </g>
235 <g
236 transform="matrix(2.1166696,0,0,2.2148216,268.56736,1243.6203)"
237 id="g52207">
238 <path
239 inkscape:connector-curvature="0"
240 style="fill:#ffffff;fill-rule:nonzero;stroke:none"
241 d="m 0,-170.06272 0,14.541 0,0.099 0.101,0 4.028,0 0.099,0 0,-0.099 0,-14.541 c 0,-2.702 0.832,-5.803 7.307,-5.803 l 0.1,0 0,-0.1 0,-4.021 0,-0.1 -0.1,0 c -10.037,0 -11.535,6.28 -11.535,10.024"
242 id="path52209" />
243 </g>
244 <g
245 transform="matrix(2.1166696,0,0,2.2148216,200.10636,1257.9899)"
246 id="g52211">
247 <path
248 inkscape:connector-curvature="0"
249 style="fill:#ffffff;fill-rule:nonzero;stroke:none"
250 d="m 0,-170.06272 -0.089,-0.047 -0.045,0.09 c -0.65,1.246 -1.641,2.32 -2.866,3.105 -3.835,2.416 -8.919,1.268 -11.336,-2.558 -1.174,-1.85 -1.553,-4.049 -1.07,-6.194 0.484,-2.142 1.767,-3.968 3.619,-5.136 2.725,-1.721 6.201,-1.678 8.898,0.092 l -7.255,5.951 -0.077,0.062 0.062,0.076 2.484,3.09 0.064,0.078 0.078,-0.064 10.634,-8.736 0.074,-0.063 -0.059,-0.078 -0.068,-0.088 c -1.755,-2.775 -4.502,-4.70901 -7.729,-5.43401 -3.224,-0.726 -6.533,-0.154 -9.317,1.60801 -2.788,1.758 -4.723,4.5 -5.449,7.723 -0.732,3.228 -0.162,6.542 1.599,9.332 3.644,5.759 11.295,7.486 17.063,3.843 1.82,-1.148 3.315,-2.765 4.326,-4.674 l 0.047,-0.089 -0.089,-0.047 -3.499,-1.842 z"
251 id="path52213" />
252 </g>
253 <g
254 transform="matrix(2.1166696,0,0,2.2148216,446.35715,1257.9899)"
255 id="g52215">
256 <path
257 inkscape:connector-curvature="0"
258 style="fill:#ffffff;fill-rule:nonzero;stroke:none"
259 d="m 0,-170.06272 -0.088,-0.047 -0.045,0.09 c -0.652,1.246 -1.644,2.318 -2.869,3.105 -3.832,2.414 -8.919,1.268 -11.34,-2.558 -1.172,-1.852 -1.547,-4.051 -1.062,-6.196 0.482,-2.144 1.767,-3.966 3.614,-5.134 2.73,-1.721 6.204,-1.678 8.897,0.092 l -7.253,5.951 -0.077,0.062 0.065,0.076 2.485,3.09 0.064,0.078 0.077,-0.064 10.634,-8.736 0.076,-0.063 -0.061,-0.08 -0.07,-0.088 0.006,0.01 c -3.645,-5.75601 -11.294,-7.47701 -17.047,-3.834 -2.791,1.756 -4.731,4.498 -5.457,7.719 -0.731,3.23 -0.164,6.543 1.597,9.336 3.651,5.757 11.304,7.482 17.065,3.843 1.824,-1.148 3.322,-2.765 4.33,-4.674 l 0.045,-0.089 -0.09,-0.047 -3.496,-1.842 z"
260 id="path52217" />
261 </g>
262 <g
263 id="g56347"
264 clip-path="url(#id786)"
265 transform="matrix(1,0,0,-1,-328.30292,933.75171)">
266 <g
267 id="g56349"
268 transform="matrix(0.0384521,0,0,-0.0384521,58.949158,55.939194)">
269 <path
270 id="path56351"
271 d="m 0,0 -11.3,0 0,-11.5 -5,0 0,28.801 5,0 0,-12.301 0.5,-0.699 10.1,0 0.7,0.5 0,12.5 5,0 0,-28.801 -5,0 L 0,0 z"
272 style="fill:#1c4e9d;fill-rule:nonzero;stroke:none"
273 inkscape:connector-curvature="0" />
274 </g>
275 <g
276 id="g56353"
277 transform="matrix(0.0384521,0,0,-0.0384521,60.075806,56.381393)">
278 <path
279 id="path56355"
280 d="m 0,0 -10.6,28.801 5.1,0 2.4,-6.5 11.5,0 2.4,6.5 L 16.1,28.5 5.5,0 0,0 z M -1,17.7 C -0.1,14 1.1,9.801 2.6,6 4.3,9.5 5.2,13.7 6.5,17.5 L -1,17.7"
281 style="fill:#1c4e9d;fill-rule:nonzero;stroke:none"
282 inkscape:connector-curvature="0" />
283 </g>
284 <g
285 id="g56357"
286 transform="matrix(0.0384521,0,0,-0.0384521,61.883057,55.550842)">
287 <path
288 id="path56359"
289 d="m 0,0 c -4.3,-6.7 -6.8,-14.6 -10.8,-21.6 l -6,0 0,28.801 4.6,0 0.2,-21.601 c 3.8,6.9 7.3,14.3 10.6,21.601 l 6.201,0 0,-28.801 -4.5,0 L 0,0"
290 style="fill:#1c4e9d;fill-rule:nonzero;stroke:none"
291 inkscape:connector-curvature="0" />
292 </g>
293 <g
294 id="g56361"
295 transform="matrix(0.0384521,0,0,-0.0384521,63.478821,55.550842)">
296 <path
297 id="path56363"
298 d="m 0,0 c -3.8,-7.1 -6.699,-14.5 -10.5,-21.6 l -6.3,0 0,28.801 4.8,0 0.301,-21.601 c 3.599,6.9 7.099,14.3 10.5,21.601 l 6.299,0 0,-28.801 -4.799,0.2 L 0,0"
299 style="fill:#1c4e9d;fill-rule:nonzero;stroke:none"
300 inkscape:connector-curvature="0" />
301 </g>
302 <g
303 id="g56365"
304 transform="matrix(0.0384521,0,0,-0.0384521,65.139938,56.223755)">
305 <path
306 id="path56367"
307 d="m 0,0 -0.2,-4.1 -17.8,0 0,28.801 18,0 0,-4.301 -12.899,-0.3 0.199,-7.7 11.301,0 0,-3.8 -11.5,-0.5 L -12.7,0.201 0,0 z"
308 style="fill:#1c4e9d;fill-rule:nonzero;stroke:none"
309 inkscape:connector-curvature="0" />
310 </g>
311 <g
312 id="g56369"
313 transform="matrix(0.0384521,0,0,-0.0384521,66.06279,56.381393)">
314 <path
315 id="path56371"
316 d="m 0,0 -4.8,0 0,28.801 16.3,0 0,-4.301 -11,0 L 0,0 z"
317 style="fill:#1c4e9d;fill-rule:nonzero;stroke:none"
318 inkscape:connector-curvature="0" />
319 </g>
320 </g>
321 </g>
322</svg>
0323
=== added file 'tests/unit/cnet/images/euronews-art.png'
1Binary files tests/unit/cnet/images/euronews-art.png 1970-01-01 00:00:00 +0000 and tests/unit/cnet/images/euronews-art.png 2015-05-20 13:57:15 +0000 differ324Binary files tests/unit/cnet/images/euronews-art.png 1970-01-01 00:00:00 +0000 and tests/unit/cnet/images/euronews-art.png 2015-05-20 13:57:15 +0000 differ
=== added file 'tests/unit/cnet/images/logo.png'
2Binary files tests/unit/cnet/images/logo.png 1970-01-01 00:00:00 +0000 and tests/unit/cnet/images/logo.png 2015-05-20 13:57:15 +0000 differ325Binary files tests/unit/cnet/images/logo.png 1970-01-01 00:00:00 +0000 and tests/unit/cnet/images/logo.png 2015-05-20 13:57:15 +0000 differ
=== added directory 'tests/unit/cnet/renderer'
=== added file 'tests/unit/cnet/renderer/carousel.json'
--- tests/unit/cnet/renderer/carousel.json 1970-01-01 00:00:00 +0000
+++ tests/unit/cnet/renderer/carousel.json 2015-05-20 13:57:15 +0000
@@ -0,0 +1,12 @@
1{
2 "schema-version": 1,
3 "template": {
4 "category-layout": "carousel",
5 "card-size": "medium",
6 "overlay": true
7 },
8 "components": {
9 "title": "title",
10 "art": "image"
11 }
12}
013
=== added file 'tests/unit/cnet/renderer/hgrid.json'
--- tests/unit/cnet/renderer/hgrid.json 1970-01-01 00:00:00 +0000
+++ tests/unit/cnet/renderer/hgrid.json 2015-05-20 13:57:15 +0000
@@ -0,0 +1,15 @@
1{
2 "schema-version": 1,
3 "template": {
4 "category-layout": "grid",
5 "card-layout": "horizontal",
6 "card-size": "medium",
7 "collapsed-rows": 0
8 },
9 "components": {
10 "mascot": "image",
11 "title": "title",
12 "subtitle": "subtitle",
13 "summary": "summary"
14 }
15}
016
=== added file 'tests/unit/cnet/renderer/journal.json'
--- tests/unit/cnet/renderer/journal.json 1970-01-01 00:00:00 +0000
+++ tests/unit/cnet/renderer/journal.json 2015-05-20 13:57:15 +0000
@@ -0,0 +1,16 @@
1{
2 "schema-version": 1,
3 "template": {
4 "category-layout": "vertical-journal",
5 "card-layout": "horizontal",
6 "card-size": "large",
7 "collapsed-rows": 0
8 },
9 "components": {
10 "art": "image",
11 "title": "title",
12 "subtitle": "subtitle",
13 "summary": "summary",
14 "attributes": "attributes"
15 }
16}
017
=== added file 'tests/unit/cnet/renderer/large.json'
--- tests/unit/cnet/renderer/large.json 1970-01-01 00:00:00 +0000
+++ tests/unit/cnet/renderer/large.json 2015-05-20 13:57:15 +0000
@@ -0,0 +1,14 @@
1{
2 "schema-version": 1,
3 "template": {
4 "category-layout": "grid",
5 "card-size": "large",
6 "overlay": true,
7 "collapsed-rows": 0
8 },
9 "components": {
10 "art": "image",
11 "title": "title",
12 "subtitle": "subtitle"
13 }
14}
015
=== added file 'tests/unit/cnet/renderer/wide-art.json'
--- tests/unit/cnet/renderer/wide-art.json 1970-01-01 00:00:00 +0000
+++ tests/unit/cnet/renderer/wide-art.json 2015-05-20 13:57:15 +0000
@@ -0,0 +1,13 @@
1{
2 "schema-version": 1,
3 "template": {
4 "category-layout": "grid",
5 "card-size": "large",
6 "overlay": true,
7 "collapsed-rows": 0
8 },
9 "components": {
10 "title": "title",
11 "art": { "field": "image", "aspect-ratio": 2.5 }
12 }
13}
014
=== added file 'tests/unit/cnet/rss.ssweeny_rss.ini.in'
--- tests/unit/cnet/rss.ssweeny_rss.ini.in 1970-01-01 00:00:00 +0000
+++ tests/unit/cnet/rss.ssweeny_rss.ini.in 2015-05-20 13:57:15 +0000
@@ -0,0 +1,11 @@
1[ScopeConfig]
2_DisplayName=CNet
3_Description=CNet
4Art=screenshot.png
5Author=Scott Sweeny
6Icon=icon.png
7
8[Appearance]
9PageHeader.Logo=logo.png
10PageHeader.Background=color:///#e9e7e8
11PageHeader.DividerColor=#ffeb00
012
=== added directory 'tests/unit/elpais'
=== added file 'tests/unit/elpais/CMakeLists.txt'
--- tests/unit/elpais/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ tests/unit/elpais/CMakeLists.txt 2015-05-20 13:57:15 +0000
@@ -0,0 +1,11 @@
1# Put the ini file in the build directory next to the scope
2# .so file so test tools can find both easily.
3configure_file(scope.ini.in ../src/${SCOPE_PACKAGE}_${SCOPE_NAME}.ini)
4
5INSTALL(FILES ${CMAKE_BINARY_DIR}/src/${SCOPE_PACKAGE}_${SCOPE_NAME}.ini
6DESTINATION ${INI_INSTALLDIR})
7
8INSTALL(
9 DIRECTORY "images"
10 DESTINATION ${SCOPE_INSTALLDIR}
11)
012
=== added directory 'tests/unit/elpais/caching'
=== added file 'tests/unit/elpais/feeds.json'
--- tests/unit/elpais/feeds.json 1970-01-01 00:00:00 +0000
+++ tests/unit/elpais/feeds.json 2015-05-20 13:57:15 +0000
@@ -0,0 +1,6 @@
1[
2 {
3 "label": "All",
4 "id": "http://127.0.0.1:9999/elpais/portada.xml"
5 }
6]
07
=== added directory 'tests/unit/elpais/images'
=== added file 'tests/unit/elpais/images/EL_PAIS.png'
1Binary files tests/unit/elpais/images/EL_PAIS.png 1970-01-01 00:00:00 +0000 and tests/unit/elpais/images/EL_PAIS.png 2015-05-20 13:57:15 +0000 differ8Binary files tests/unit/elpais/images/EL_PAIS.png 1970-01-01 00:00:00 +0000 and tests/unit/elpais/images/EL_PAIS.png 2015-05-20 13:57:15 +0000 differ
=== added file 'tests/unit/elpais/images/default.png'
2Binary files tests/unit/elpais/images/default.png 1970-01-01 00:00:00 +0000 and tests/unit/elpais/images/default.png 2015-05-20 13:57:15 +0000 differ9Binary files tests/unit/elpais/images/default.png 1970-01-01 00:00:00 +0000 and tests/unit/elpais/images/default.png 2015-05-20 13:57:15 +0000 differ
=== added file 'tests/unit/elpais/images/error.png'
3Binary files tests/unit/elpais/images/error.png 1970-01-01 00:00:00 +0000 and tests/unit/elpais/images/error.png 2015-05-20 13:57:15 +0000 differ10Binary files tests/unit/elpais/images/error.png 1970-01-01 00:00:00 +0000 and tests/unit/elpais/images/error.png 2015-05-20 13:57:15 +0000 differ
=== added file 'tests/unit/elpais/images/logo.png'
4Binary files tests/unit/elpais/images/logo.png 1970-01-01 00:00:00 +0000 and tests/unit/elpais/images/logo.png 2015-05-20 13:57:15 +0000 differ11Binary files tests/unit/elpais/images/logo.png 1970-01-01 00:00:00 +0000 and tests/unit/elpais/images/logo.png 2015-05-20 13:57:15 +0000 differ
=== added file 'tests/unit/elpais/scope.ini.in'
--- tests/unit/elpais/scope.ini.in 1970-01-01 00:00:00 +0000
+++ tests/unit/elpais/scope.ini.in 2015-05-20 13:57:15 +0000
@@ -0,0 +1,16 @@
1[ScopeConfig]
2DisplayName = EL PAÍS
3Description = This is EL PAÍS scope
4Author = Grupo Prisa
5Art = ./images/default.png
6Icon = ./images/logo.png
7SearchHint = Titular de noticia
8HotKey = ELPAISscope.HotKey
9[Appearance]
10background=color:///#FFFFFF
11PageHeader.Logo=./images/EL_PAIS.png
12backgroundColor=#F0F0F0
13PageHeader.Background=color:///#FFFFFF
14PageHeader.ForegroundColor=#333333
15PageHeader.DividerColor=#333333
16PreviewButtonColor=#F0F0F0
017
=== added directory 'tests/unit/euronews'
=== added file 'tests/unit/euronews/CMakeLists.txt'
--- tests/unit/euronews/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ tests/unit/euronews/CMakeLists.txt 2015-05-20 13:57:15 +0000
@@ -0,0 +1,23 @@
1# Put the ini file in the build directory next to the scope
2# .so file so test tools can find both easily.
3CONFIGURE_FILE(
4 rss-scope.ini.in
5 ${CMAKE_BINARY_DIR}/src/${SO_NAME}.ini
6)
7
8INSTALL(
9 FILES ${CMAKE_BINARY_DIR}/src/${SO_NAME}.ini
10 DESTINATION ${INI_INSTALLDIR}
11)
12INSTALL(
13 FILES departments.json
14 DESTINATION ${SCOPE_INSTALLDIR}
15)
16INSTALL(
17 DIRECTORY "renderer"
18 DESTINATION ${SCOPE_INSTALLDIR}
19)
20INSTALL(
21 DIRECTORY "images"
22 DESTINATION ${SCOPE_INSTALLDIR}
23)
024
=== added file 'tests/unit/euronews/feeds.json'
--- tests/unit/euronews/feeds.json 1970-01-01 00:00:00 +0000
+++ tests/unit/euronews/feeds.json 2015-05-20 13:57:15 +0000
@@ -0,0 +1,26 @@
1[
2 {
3 "label": "News",
4 "id": "http://127.0.0.1:9999/euronews/_partners/ubuntu/news.xml"
5 },
6 {
7 "label": "Business",
8 "id": "http://127.0.0.1:9999/euronews/_partners/ubuntu/business.xml"
9 },
10 {
11 "label": "Europe",
12 "id": "http://127.0.0.1:9999/euronews/_partners/ubuntu/europe.xml"
13 },
14 {
15 "label": "Culture",
16 "id": "http://127.0.0.1:9999/euronews/_partners/ubuntu/culture.xml"
17 },
18 {
19 "label": "Sci-tech",
20 "id": "http://127.0.0.1:9999/euronews/_partners/ubuntu/scitech.xml"
21 },
22 {
23 "label": "No comment",
24 "id": "http://127.0.0.1:9999/euronews/_partners/ubuntu/nocomment.xml"
25 }
26]
027
=== added file 'tests/unit/euronews/icon.svg'
--- tests/unit/euronews/icon.svg 1970-01-01 00:00:00 +0000
+++ tests/unit/euronews/icon.svg 2015-05-20 13:57:15 +0000
@@ -0,0 +1,92 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!-- Created with Inkscape (http://www.inkscape.org/) -->
3<svg
4 xmlns:svg="http://www.w3.org/2000/svg"
5 xmlns="http://www.w3.org/2000/svg"
6 version="1.0"
7 width="544.00006"
8 height="544"
9 id="svg2">
10 <defs
11 id="defs4" />
12 <g
13 transform="translate(-6.4712476,3.0971002)"
14 id="layer1">
15 <g
16 transform="matrix(0.8880597,0,0,0.8880597,0.7243933,-0.3466903)"
17 id="g3208">
18 <g
19 transform="matrix(34.669279,0,0,-34.669276,312.75001,137.48351)"
20 id="g17052">
21 <path
22 d="M 0,0 C -1.891,0 -3.424,-1.533 -3.424,-3.425 C -3.424,-5.316 -1.891,-6.849 0,-6.849 C 1.891,-6.849 3.424,-5.316 3.424,-3.425 C 3.424,-1.533 1.891,0 0,0"
23 id="path17054"
24 style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" />
25 </g>
26 <g
27 transform="matrix(34.669279,0,0,-34.669276,207.7853,422.93993)"
28 id="g17056">
29 <path
30 d="M 0,0 L -0.005,0 L -0.005,-0.757 C -0.005,-0.85 -0.038,-0.935 -0.098,-0.996 C -0.155,-1.056 -0.232,-1.089 -0.314,-1.089 C -0.396,-1.089 -0.473,-1.056 -0.53,-0.996 C -0.59,-0.935 -0.622,-0.85 -0.622,-0.757 L -0.622,0 L -0.869,0 L -0.869,-0.757 C -0.869,-0.922 -0.815,-1.065 -0.711,-1.169 C -0.61,-1.27 -0.469,-1.325 -0.314,-1.325 C -0.159,-1.325 -0.018,-1.27 0.083,-1.169 C 0.187,-1.065 0.242,-0.922 0.242,-0.757 L 0.242,0 L 0.237,0"
31 id="path17058"
32 style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" />
33 </g>
34 <g
35 transform="matrix(34.669279,0,0,-34.669276,280.39317,456.46858)"
36 id="g17060">
37 <path
38 d="M 0,0 C -0.075,-0.079 -0.181,-0.122 -0.298,-0.122 C -0.416,-0.122 -0.522,-0.079 -0.597,0 C -0.673,0.079 -0.714,0.192 -0.714,0.317 C -0.714,0.442 -0.673,0.556 -0.597,0.635 C -0.522,0.714 -0.416,0.757 -0.298,0.757 C -0.181,0.757 -0.075,0.714 0,0.635 C 0.076,0.556 0.117,0.442 0.117,0.317 C 0.117,0.192 0.076,0.079 0,0 M 0.173,0.806 C 0.048,0.927 -0.121,0.994 -0.298,0.994 C -0.477,0.994 -0.645,0.927 -0.77,0.806 C -0.901,0.68 -0.972,0.507 -0.972,0.317 C -0.972,0.128 -0.901,-0.045 -0.77,-0.171 C -0.645,-0.292 -0.477,-0.358 -0.298,-0.358 C -0.121,-0.358 0.048,-0.292 0.173,-0.171 C 0.304,-0.045 0.375,0.128 0.375,0.317 C 0.375,0.507 0.304,0.68 0.173,0.806"
39 id="path17062"
40 style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" />
41 </g>
42 <g
43 transform="matrix(34.669279,0,0,-34.669276,319.16729,422.00733)"
44 id="g17064">
45 <path
46 d="M 0,0 C -0.155,0 -0.296,-0.055 -0.397,-0.157 C -0.5,-0.261 -0.556,-0.404 -0.556,-0.569 L -0.556,-1.326 L -0.309,-1.326 L -0.309,-0.569 C -0.309,-0.476 -0.276,-0.391 -0.217,-0.329 C -0.159,-0.269 -0.082,-0.237 0,-0.237 C 0.082,-0.237 0.159,-0.269 0.216,-0.329 C 0.276,-0.391 0.309,-0.476 0.309,-0.569 L 0.309,-1.326 L 0.556,-1.326 L 0.556,-0.569 C 0.556,-0.404 0.501,-0.261 0.397,-0.157 C 0.296,-0.055 0.155,0 0,0"
47 id="path17066"
48 style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" />
49 </g>
50 <g
51 transform="matrix(34.669279,0,0,-34.669276,447.51643,422.93993)"
52 id="g17068">
53 <path
54 d="M 0,0 L -0.005,0 L -0.005,-0.827 C -0.005,-0.986 -0.094,-1.089 -0.231,-1.089 C -0.395,-1.089 -0.478,-0.988 -0.478,-0.789 L -0.478,0 L -0.725,0 L -0.725,-0.789 C -0.725,-0.988 -0.808,-1.089 -0.972,-1.089 C -1.109,-1.089 -1.197,-0.986 -1.197,-0.827 L -1.197,0 L -1.444,0 L -1.444,-0.88 C -1.444,-1.13 -1.239,-1.325 -0.977,-1.325 C -0.819,-1.325 -0.683,-1.26 -0.601,-1.147 C -0.519,-1.26 -0.383,-1.325 -0.225,-1.325 C 0.036,-1.325 0.242,-1.13 0.242,-0.88 L 0.242,0 L 0.237,0"
55 id="path17070"
56 style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" />
57 </g>
58 <g
59 transform="matrix(34.669279,0,0,-34.669276,482.0401,440.7114)"
60 id="g17072">
61 <path
62 d="M 0,0 C -0.158,0.044 -0.294,0.082 -0.294,0.169 C -0.289,0.242 -0.265,0.277 -0.146,0.277 L 0.455,0.277 L 0.455,0.513 L -0.106,0.513 C -0.393,0.513 -0.552,0.387 -0.552,0.158 C -0.552,0.042 -0.497,-0.049 -0.384,-0.119 C -0.287,-0.179 -0.159,-0.216 -0.046,-0.249 C 0.119,-0.296 0.262,-0.337 0.262,-0.432 C 0.262,-0.514 0.216,-0.55 0.114,-0.55 L -0.552,-0.55 L -0.552,-0.787 L 0.114,-0.787 C 0.232,-0.787 0.332,-0.756 0.403,-0.697 C 0.479,-0.634 0.52,-0.538 0.52,-0.422 C 0.52,-0.145 0.232,-0.065 0,0"
63 id="path17074"
64 style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" />
65 </g>
66 <g
67 transform="matrix(34.669279,0,0,-34.669276,223.62569,440.00761)"
68 id="g17076">
69 <path
70 d="M 0,0 L 0,-0.796 L 0.23,-0.796 L 0.23,0 C 0.23,0.147 0.275,0.315 0.627,0.315 L 0.633,0.315 L 0.633,0.545 L 0.627,0.545 C 0.082,0.545 0,0.203 0,0"
71 id="path17078"
72 style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" />
73 </g>
74 <g
75 transform="matrix(34.669279,0,0,-34.669276,162.68056,452.232)"
76 id="g17080">
77 <path
78 d="M 0,0 L -0.005,0.002 L -0.007,-0.003 C -0.043,-0.07 -0.096,-0.129 -0.163,-0.171 C -0.371,-0.303 -0.648,-0.24 -0.779,-0.032 C -0.843,0.068 -0.864,0.188 -0.837,0.304 C -0.811,0.421 -0.741,0.52 -0.641,0.584 C -0.492,0.677 -0.303,0.675 -0.157,0.579 L -0.551,0.255 L -0.556,0.252 L -0.552,0.248 L -0.417,0.08 L -0.414,0.075 L -0.41,0.079 L 0.169,0.554 L 0.172,0.557 L 0.17,0.561 L 0.166,0.566 C 0.07,0.717 -0.079,0.822 -0.255,0.861 C -0.43,0.901 -0.61,0.87 -0.761,0.774 C -0.912,0.679 -1.018,0.53 -1.057,0.355 C -1.097,0.179 -1.066,-0.001 -0.97,-0.153 C -0.772,-0.466 -0.356,-0.56 -0.043,-0.362 C 0.056,-0.299 0.137,-0.212 0.192,-0.108 L 0.195,-0.103 L 0.19,-0.1"
79 id="path17082"
80 style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" />
81 </g>
82 <g
83 transform="matrix(34.669279,0,0,-34.669276,381.92215,452.232)"
84 id="g17084">
85 <path
86 d="M 0,0 L -0.005,0.002 L -0.008,-0.003 C -0.043,-0.07 -0.097,-0.129 -0.163,-0.171 C -0.371,-0.303 -0.648,-0.24 -0.78,-0.032 C -0.843,0.068 -0.864,0.188 -0.838,0.305 C -0.811,0.421 -0.741,0.52 -0.641,0.584 C -0.493,0.677 -0.304,0.675 -0.157,0.579 L -0.552,0.255 L -0.556,0.252 L -0.552,0.248 L -0.417,0.08 L -0.414,0.075 L -0.409,0.079 L 0.168,0.554 L 0.173,0.557 L 0.169,0.561 L 0.166,0.566 L 0.166,0.566 C -0.032,0.879 -0.448,0.972 -0.761,0.774 C -0.913,0.679 -1.018,0.53 -1.057,0.355 C -1.097,0.179 -1.066,-0.001 -0.971,-0.153 C -0.772,-0.466 -0.356,-0.56 -0.043,-0.362 C 0.056,-0.299 0.137,-0.212 0.192,-0.108 L 0.195,-0.103 L 0.19,-0.1"
87 id="path17086"
88 style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" />
89 </g>
90 </g>
91 </g>
92</svg>
093
=== added directory 'tests/unit/euronews/images'
=== added file 'tests/unit/euronews/images/default.png'
1Binary files tests/unit/euronews/images/default.png 1970-01-01 00:00:00 +0000 and tests/unit/euronews/images/default.png 2015-05-20 13:57:15 +0000 differ94Binary files tests/unit/euronews/images/default.png 1970-01-01 00:00:00 +0000 and tests/unit/euronews/images/default.png 2015-05-20 13:57:15 +0000 differ
=== added file 'tests/unit/euronews/images/default.svg'
--- tests/unit/euronews/images/default.svg 1970-01-01 00:00:00 +0000
+++ tests/unit/euronews/images/default.svg 2015-05-20 13:57:15 +0000
@@ -0,0 +1,322 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!-- Created with Inkscape (http://www.inkscape.org/) -->
3
4<svg
5 xmlns:dc="http://purl.org/dc/elements/1.1/"
6 xmlns:cc="http://creativecommons.org/ns#"
7 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
8 xmlns:svg="http://www.w3.org/2000/svg"
9 xmlns="http://www.w3.org/2000/svg"
10 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12 width="720"
13 height="330"
14 id="svg2"
15 sodipodi:version="0.32"
16 inkscape:version="0.48.4 r9939"
17 version="1.0"
18 sodipodi:docname="default.svg.old"
19 inkscape:output_extension="org.inkscape.output.svg.inkscape">
20 <defs
21 id="defs4" />
22 <sodipodi:namedview
23 id="base"
24 pagecolor="#ffffff"
25 bordercolor="#666666"
26 borderopacity="1.0"
27 gridtolerance="10000"
28 guidetolerance="10"
29 objecttolerance="10"
30 inkscape:pageopacity="0.0"
31 inkscape:pageshadow="2"
32 inkscape:zoom="0.88003809"
33 inkscape:cx="490.40724"
34 inkscape:cy="124.4655"
35 inkscape:document-units="px"
36 inkscape:current-layer="layer1"
37 height="24px"
38 width="24px"
39 showgrid="true"
40 inkscape:window-width="1366"
41 inkscape:window-height="744"
42 inkscape:window-x="0"
43 inkscape:window-y="24"
44 inkscape:snap-nodes="true"
45 inkscape:window-maximized="1"
46 fit-margin-top="0"
47 fit-margin-left="0"
48 fit-margin-right="0"
49 fit-margin-bottom="0" />
50 <metadata
51 id="metadata7">
52 <rdf:RDF>
53 <cc:Work
54 rdf:about="">
55 <dc:format>image/svg+xml</dc:format>
56 <dc:type
57 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
58 <dc:title></dc:title>
59 </cc:Work>
60 </rdf:RDF>
61 </metadata>
62 <g
63 inkscape:label="Layer 1"
64 inkscape:groupmode="layer"
65 id="layer1"
66 transform="translate(-5.7571953,-706.0344)">
67 <g
68 id="g15405"
69 clip-path="url(#id335)"
70 transform="matrix(1,0,0,-1,-328.30292,933.75171)">
71 <g
72 id="g15407"
73 transform="matrix(0.0384521,0,0,-0.0384521,58.949158,55.939194)">
74 <path
75 id="path15409"
76 d="m 0,0 -11.3,0 0,-11.5 -5,0 0,28.801 5,0 0,-12.301 0.5,-0.699 10.1,0 0.7,0.5 0,12.5 5,0 0,-28.801 -5,0 L 0,0 z"
77 style="fill:#1c4e9d;fill-rule:nonzero;stroke:none"
78 inkscape:connector-curvature="0" />
79 </g>
80 <g
81 id="g15411"
82 transform="matrix(0.0384521,0,0,-0.0384521,60.075806,56.381393)">
83 <path
84 id="path15413"
85 d="m 0,0 -10.6,28.801 5.1,0 2.4,-6.5 11.5,0 2.4,6.5 L 16.1,28.5 5.5,0 0,0 z M -1,17.7 C -0.1,14 1.1,9.801 2.6,6 4.3,9.5 5.2,13.7 6.5,17.5 L -1,17.7"
86 style="fill:#1c4e9d;fill-rule:nonzero;stroke:none"
87 inkscape:connector-curvature="0" />
88 </g>
89 <g
90 id="g15415"
91 transform="matrix(0.0384521,0,0,-0.0384521,61.883057,55.550842)">
92 <path
93 id="path15417"
94 d="m 0,0 c -4.3,-6.7 -6.8,-14.6 -10.8,-21.6 l -6,0 0,28.801 4.6,0 0.2,-21.601 c 3.8,6.9 7.3,14.3 10.6,21.601 l 6.201,0 0,-28.801 -4.5,0 L 0,0"
95 style="fill:#1c4e9d;fill-rule:nonzero;stroke:none"
96 inkscape:connector-curvature="0" />
97 </g>
98 <g
99 id="g15419"
100 transform="matrix(0.0384521,0,0,-0.0384521,63.478821,55.550842)">
101 <path
102 id="path15421"
103 d="m 0,0 c -3.8,-7.1 -6.699,-14.5 -10.5,-21.6 l -6.3,0 0,28.801 4.8,0 0.301,-21.601 c 3.599,6.9 7.099,14.3 10.5,21.601 l 6.299,0 0,-28.801 -4.799,0.2 L 0,0"
104 style="fill:#1c4e9d;fill-rule:nonzero;stroke:none"
105 inkscape:connector-curvature="0" />
106 </g>
107 <g
108 id="g15423"
109 transform="matrix(0.0384521,0,0,-0.0384521,65.139938,56.223755)">
110 <path
111 id="path15425"
112 d="m 0,0 -0.2,-4.1 -17.8,0 0,28.801 18,0 0,-4.301 -12.899,-0.3 0.199,-7.7 11.301,0 0,-3.8 -11.5,-0.5 L -12.7,0.201 0,0 z"
113 style="fill:#1c4e9d;fill-rule:nonzero;stroke:none"
114 inkscape:connector-curvature="0" />
115 </g>
116 <g
117 id="g15427"
118 transform="matrix(0.0384521,0,0,-0.0384521,66.06279,56.381393)">
119 <path
120 id="path15429"
121 d="m 0,0 -4.8,0 0,28.801 16.3,0 0,-4.301 -11,0 L 0,0 z"
122 style="fill:#1c4e9d;fill-rule:nonzero;stroke:none"
123 inkscape:connector-curvature="0" />
124 </g>
125 </g>
126 <g
127 id="g35751"
128 clip-path="url(#id554)"
129 transform="matrix(1,0,0,-1,-328.30292,933.75171)">
130 <g
131 id="g35753"
132 transform="matrix(0.0384521,0,0,-0.0384521,58.949158,55.939194)">
133 <path
134 id="path35755"
135 d="m 0,0 -11.3,0 0,-11.5 -5,0 0,28.801 5,0 0,-12.301 0.5,-0.699 10.1,0 0.7,0.5 0,12.5 5,0 0,-28.801 -5,0 L 0,0 z"
136 style="fill:#1c4e9d;fill-rule:nonzero;stroke:none"
137 inkscape:connector-curvature="0" />
138 </g>
139 <g
140 id="g35757"
141 transform="matrix(0.0384521,0,0,-0.0384521,60.075806,56.381393)">
142 <path
143 id="path35759"
144 d="m 0,0 -10.6,28.801 5.1,0 2.4,-6.5 11.5,0 2.4,6.5 L 16.1,28.5 5.5,0 0,0 z M -1,17.7 C -0.1,14 1.1,9.801 2.6,6 4.3,9.5 5.2,13.7 6.5,17.5 L -1,17.7"
145 style="fill:#1c4e9d;fill-rule:nonzero;stroke:none"
146 inkscape:connector-curvature="0" />
147 </g>
148 <g
149 id="g35761"
150 transform="matrix(0.0384521,0,0,-0.0384521,61.883057,55.550842)">
151 <path
152 id="path35763"
153 d="m 0,0 c -4.3,-6.7 -6.8,-14.6 -10.8,-21.6 l -6,0 0,28.801 4.6,0 0.2,-21.601 c 3.8,6.9 7.3,14.3 10.6,21.601 l 6.201,0 0,-28.801 -4.5,0 L 0,0"
154 style="fill:#1c4e9d;fill-rule:nonzero;stroke:none"
155 inkscape:connector-curvature="0" />
156 </g>
157 <g
158 id="g35765"
159 transform="matrix(0.0384521,0,0,-0.0384521,63.478821,55.550842)">
160 <path
161 id="path35767"
162 d="m 0,0 c -3.8,-7.1 -6.699,-14.5 -10.5,-21.6 l -6.3,0 0,28.801 4.8,0 0.301,-21.601 c 3.599,6.9 7.099,14.3 10.5,21.601 l 6.299,0 0,-28.801 -4.799,0.2 L 0,0"
163 style="fill:#1c4e9d;fill-rule:nonzero;stroke:none"
164 inkscape:connector-curvature="0" />
165 </g>
166 <g
167 id="g35769"
168 transform="matrix(0.0384521,0,0,-0.0384521,65.139938,56.223755)">
169 <path
170 id="path35771"
171 d="m 0,0 -0.2,-4.1 -17.8,0 0,28.801 18,0 0,-4.301 -12.899,-0.3 0.199,-7.7 11.301,0 0,-3.8 -11.5,-0.5 L -12.7,0.201 0,0 z"
172 style="fill:#1c4e9d;fill-rule:nonzero;stroke:none"
173 inkscape:connector-curvature="0" />
174 </g>
175 <g
176 id="g35773"
177 transform="matrix(0.0384521,0,0,-0.0384521,66.06279,56.381393)">
178 <path
179 id="path35775"
180 d="m 0,0 -4.8,0 0,28.801 16.3,0 0,-4.301 -11,0 L 0,0 z"
181 style="fill:#1c4e9d;fill-rule:nonzero;stroke:none"
182 inkscape:connector-curvature="0" />
183 </g>
184 </g>
185 <path
186 id="path52181"
187 d="m 5.7571953,706.0344 720.0000047,0 0,330 -720.0000047,0 0,-330 z"
188 style="fill:#b6b5b5;fill-rule:nonzero;stroke:none"
189 inkscape:connector-curvature="0" />
190 <g
191 transform="matrix(2.1166696,0,0,2.2148216,250.77235,1223.5571)"
192 id="g52187">
193 <path
194 inkscape:connector-curvature="0"
195 style="fill:#ffffff;fill-rule:nonzero;stroke:none"
196 d="m 0,-170.06272 -0.101,0 0,0.1 0,13.828 c 0,1.705 -0.601,3.267 -1.695,4.404 -1.058,1.1 -2.476,1.707 -3.985,1.707 -1.509,0 -2.922,-0.607 -3.979,-1.707 -1.092,-1.135 -1.691,-2.699 -1.691,-4.404 l 0,-13.828 0,-0.1 -0.1,0 -4.345,0 -0.102,0 0,0.1 0,13.828 c 0,3.039 1.011,5.662 2.925,7.582 1.85,1.859 4.441,2.883 7.292,2.883 2.856,0 5.45,-1.024 7.305,-2.883 1.911,-1.92 2.923,-4.541 2.923,-7.582 l 0,-13.828 0,-0.1 -0.098,0 -4.349,0 z"
197 id="path52189" />
198 </g>
199 <g
200 transform="matrix(2.1166696,0,0,2.2148216,332.31519,1262.9618)"
201 id="g52191">
202 <path
203 inkscape:connector-curvature="0"
204 style="fill:#ffffff;fill-rule:nonzero;stroke:none"
205 d="m 0,-170.06272 c -1.383,1.449 -3.334,2.248 -5.489,2.248 -2.156,0 -4.106,-0.799 -5.489,-2.248 -1.392,-1.463 -2.159,-3.533 -2.159,-5.832 0,-2.307 0.767,-4.385 2.159,-5.848 1.382,-1.453 3.331,-2.252 5.489,-2.252 2.155,0 4.106,0.799 5.489,2.252 1.396,1.465 2.162,3.541 2.162,5.848 0,2.299 -0.766,4.369 -2.162,5.832 m 3.186,-14.822 c -2.312,-2.23501 -5.395,-3.46301 -8.675,-3.46301 -3.285,0 -6.368,1.228 -8.682,3.46301 -2.394,2.312 -3.712,5.506 -3.712,8.99 0,3.481 1.318,6.668 3.712,8.979 2.313,2.228 5.397,3.455 8.682,3.455 3.28,0 6.363,-1.227 8.675,-3.455 2.401,-2.311 3.719,-5.498 3.719,-8.979 0,-3.482 -1.318,-6.676 -3.719,-8.99"
206 id="path52193" />
207 </g>
208 <g
209 transform="matrix(2.1166696,0,0,2.2148216,375.87691,1222.4616)"
210 id="g52195">
211 <path
212 inkscape:connector-curvature="0"
213 style="fill:#ffffff;fill-rule:nonzero;stroke:none"
214 d="m 0,-170.06272 c -2.854,0 -5.448,1.023 -7.299,2.883 -1.914,1.92 -2.924,4.545 -2.924,7.592 l 0,13.828 0,0.099 0.1,0 4.343,0 0.1,0 0,-0.099 0,-13.828 c 0,-1.709 0.603,-3.278 1.696,-4.413 1.061,-1.103 2.476,-1.709 3.984,-1.709 1.508,0 2.925,0.606 3.982,1.709 1.094,1.135 1.693,2.704 1.693,4.413 l 0,13.828 0,0.099 0.1,0 4.355,0 0.101,0 0,-0.099 0,-13.828 c 0,-3.043 -1.012,-5.668 -2.926,-7.592 -1.857,-1.862 -4.45,-2.883 -7.305,-2.883"
215 id="path52197" />
216 </g>
217 <g
218 transform="matrix(2.1166696,0,0,2.2148216,520.04351,1223.5571)"
219 id="g52199">
220 <path
221 inkscape:connector-curvature="0"
222 style="fill:#ffffff;fill-rule:nonzero;stroke:none"
223 d="m 0,-170.06272 -0.102,0 0,0.1 0,15.115 c 0,2.93 -1.627,4.824 -4.146,4.824 -3.014,0 -4.543,-1.857 -4.543,-5.519 l 0,-14.42 0,-0.1 -0.102,0 -4.339,0 -0.1,0 0,0.1 0,14.42 c 0,3.662 -1.529,5.519 -4.547,5.519 -2.517,0 -4.146,-1.894 -4.146,-4.824 l 0,-15.115 0,-0.1 -0.098,0 -4.35,0 -0.097,0 0,0.1 0,16.09 c 0,4.599 3.777,8.203 8.599,8.203 2.889,0 5.398,-1.202 6.916,-3.293 1.502,2.091 4.008,3.293 6.909,3.293 4.816,0 8.587,-3.604 8.587,-8.203 l 0,-16.09 0,-0.1 -0.096,0 -4.345,0 z"
224 id="path52201" />
225 </g>
226 <g
227 transform="matrix(2.1166696,0,0,2.2148216,558.82208,1244.4554)"
228 id="g52203">
229 <path
230 inkscape:connector-curvature="0"
231 style="fill:#ffffff;fill-rule:nonzero;stroke:none"
232 d="m 0,-170.06272 c -2.902,-0.809 -5.408,-1.51 -5.408,-3.108 0.095,-1.344 0.525,-1.984 2.713,-1.984 l 10.966,0 0.098,0 0,-0.1 0,-4.144 0,-0.1 -0.098,0 -10.222,0 c -5.289,0 -8.201,2.315 -8.201,6.52 0,2.15 1.007,3.82 3.08,5.105 1.793,1.111 4.144,1.785 6.224,2.383 3.036,0.871 5.661,1.625 5.661,3.383 0,1.496 -0.838,2.164 -2.713,2.164 l -12.153,0 -0.099,0 0,0.099 0,4.155 0,0.099 0.099,0 12.153,0 c 2.175,0 4.013,-0.57 5.31,-1.65 1.403,-1.166 2.141,-2.916 2.141,-5.065 0,-5.091 -5.295,-6.57 -9.551,-7.757"
233 id="path52205" />
234 </g>
235 <g
236 transform="matrix(2.1166696,0,0,2.2148216,268.56736,1243.6203)"
237 id="g52207">
238 <path
239 inkscape:connector-curvature="0"
240 style="fill:#ffffff;fill-rule:nonzero;stroke:none"
241 d="m 0,-170.06272 0,14.541 0,0.099 0.101,0 4.028,0 0.099,0 0,-0.099 0,-14.541 c 0,-2.702 0.832,-5.803 7.307,-5.803 l 0.1,0 0,-0.1 0,-4.021 0,-0.1 -0.1,0 c -10.037,0 -11.535,6.28 -11.535,10.024"
242 id="path52209" />
243 </g>
244 <g
245 transform="matrix(2.1166696,0,0,2.2148216,200.10636,1257.9899)"
246 id="g52211">
247 <path
248 inkscape:connector-curvature="0"
249 style="fill:#ffffff;fill-rule:nonzero;stroke:none"
250 d="m 0,-170.06272 -0.089,-0.047 -0.045,0.09 c -0.65,1.246 -1.641,2.32 -2.866,3.105 -3.835,2.416 -8.919,1.268 -11.336,-2.558 -1.174,-1.85 -1.553,-4.049 -1.07,-6.194 0.484,-2.142 1.767,-3.968 3.619,-5.136 2.725,-1.721 6.201,-1.678 8.898,0.092 l -7.255,5.951 -0.077,0.062 0.062,0.076 2.484,3.09 0.064,0.078 0.078,-0.064 10.634,-8.736 0.074,-0.063 -0.059,-0.078 -0.068,-0.088 c -1.755,-2.775 -4.502,-4.70901 -7.729,-5.43401 -3.224,-0.726 -6.533,-0.154 -9.317,1.60801 -2.788,1.758 -4.723,4.5 -5.449,7.723 -0.732,3.228 -0.162,6.542 1.599,9.332 3.644,5.759 11.295,7.486 17.063,3.843 1.82,-1.148 3.315,-2.765 4.326,-4.674 l 0.047,-0.089 -0.089,-0.047 -3.499,-1.842 z"
251 id="path52213" />
252 </g>
253 <g
254 transform="matrix(2.1166696,0,0,2.2148216,446.35715,1257.9899)"
255 id="g52215">
256 <path
257 inkscape:connector-curvature="0"
258 style="fill:#ffffff;fill-rule:nonzero;stroke:none"
259 d="m 0,-170.06272 -0.088,-0.047 -0.045,0.09 c -0.652,1.246 -1.644,2.318 -2.869,3.105 -3.832,2.414 -8.919,1.268 -11.34,-2.558 -1.172,-1.852 -1.547,-4.051 -1.062,-6.196 0.482,-2.144 1.767,-3.966 3.614,-5.134 2.73,-1.721 6.204,-1.678 8.897,0.092 l -7.253,5.951 -0.077,0.062 0.065,0.076 2.485,3.09 0.064,0.078 0.077,-0.064 10.634,-8.736 0.076,-0.063 -0.061,-0.08 -0.07,-0.088 0.006,0.01 c -3.645,-5.75601 -11.294,-7.47701 -17.047,-3.834 -2.791,1.756 -4.731,4.498 -5.457,7.719 -0.731,3.23 -0.164,6.543 1.597,9.336 3.651,5.757 11.304,7.482 17.065,3.843 1.824,-1.148 3.322,-2.765 4.33,-4.674 l 0.045,-0.089 -0.09,-0.047 -3.496,-1.842 z"
260 id="path52217" />
261 </g>
262 <g
263 id="g56347"
264 clip-path="url(#id786)"
265 transform="matrix(1,0,0,-1,-328.30292,933.75171)">
266 <g
267 id="g56349"
268 transform="matrix(0.0384521,0,0,-0.0384521,58.949158,55.939194)">
269 <path
270 id="path56351"
271 d="m 0,0 -11.3,0 0,-11.5 -5,0 0,28.801 5,0 0,-12.301 0.5,-0.699 10.1,0 0.7,0.5 0,12.5 5,0 0,-28.801 -5,0 L 0,0 z"
272 style="fill:#1c4e9d;fill-rule:nonzero;stroke:none"
273 inkscape:connector-curvature="0" />
274 </g>
275 <g
276 id="g56353"
277 transform="matrix(0.0384521,0,0,-0.0384521,60.075806,56.381393)">
278 <path
279 id="path56355"
280 d="m 0,0 -10.6,28.801 5.1,0 2.4,-6.5 11.5,0 2.4,6.5 L 16.1,28.5 5.5,0 0,0 z M -1,17.7 C -0.1,14 1.1,9.801 2.6,6 4.3,9.5 5.2,13.7 6.5,17.5 L -1,17.7"
281 style="fill:#1c4e9d;fill-rule:nonzero;stroke:none"
282 inkscape:connector-curvature="0" />
283 </g>
284 <g
285 id="g56357"
286 transform="matrix(0.0384521,0,0,-0.0384521,61.883057,55.550842)">
287 <path
288 id="path56359"
289 d="m 0,0 c -4.3,-6.7 -6.8,-14.6 -10.8,-21.6 l -6,0 0,28.801 4.6,0 0.2,-21.601 c 3.8,6.9 7.3,14.3 10.6,21.601 l 6.201,0 0,-28.801 -4.5,0 L 0,0"
290 style="fill:#1c4e9d;fill-rule:nonzero;stroke:none"
291 inkscape:connector-curvature="0" />
292 </g>
293 <g
294 id="g56361"
295 transform="matrix(0.0384521,0,0,-0.0384521,63.478821,55.550842)">
296 <path
297 id="path56363"
298 d="m 0,0 c -3.8,-7.1 -6.699,-14.5 -10.5,-21.6 l -6.3,0 0,28.801 4.8,0 0.301,-21.601 c 3.599,6.9 7.099,14.3 10.5,21.601 l 6.299,0 0,-28.801 -4.799,0.2 L 0,0"
299 style="fill:#1c4e9d;fill-rule:nonzero;stroke:none"
300 inkscape:connector-curvature="0" />
301 </g>
302 <g
303 id="g56365"
304 transform="matrix(0.0384521,0,0,-0.0384521,65.139938,56.223755)">
305 <path
306 id="path56367"
307 d="m 0,0 -0.2,-4.1 -17.8,0 0,28.801 18,0 0,-4.301 -12.899,-0.3 0.199,-7.7 11.301,0 0,-3.8 -11.5,-0.5 L -12.7,0.201 0,0 z"
308 style="fill:#1c4e9d;fill-rule:nonzero;stroke:none"
309 inkscape:connector-curvature="0" />
310 </g>
311 <g
312 id="g56369"
313 transform="matrix(0.0384521,0,0,-0.0384521,66.06279,56.381393)">
314 <path
315 id="path56371"
316 d="m 0,0 -4.8,0 0,28.801 16.3,0 0,-4.301 -11,0 L 0,0 z"
317 style="fill:#1c4e9d;fill-rule:nonzero;stroke:none"
318 inkscape:connector-curvature="0" />
319 </g>
320 </g>
321 </g>
322</svg>
0323
=== added file 'tests/unit/euronews/images/euronews-art.png'
1Binary files tests/unit/euronews/images/euronews-art.png 1970-01-01 00:00:00 +0000 and tests/unit/euronews/images/euronews-art.png 2015-05-20 13:57:15 +0000 differ324Binary files tests/unit/euronews/images/euronews-art.png 1970-01-01 00:00:00 +0000 and tests/unit/euronews/images/euronews-art.png 2015-05-20 13:57:15 +0000 differ
=== added file 'tests/unit/euronews/images/logo.png'
2Binary files tests/unit/euronews/images/logo.png 1970-01-01 00:00:00 +0000 and tests/unit/euronews/images/logo.png 2015-05-20 13:57:15 +0000 differ325Binary files tests/unit/euronews/images/logo.png 1970-01-01 00:00:00 +0000 and tests/unit/euronews/images/logo.png 2015-05-20 13:57:15 +0000 differ
=== added file 'tests/unit/euronews/preview-card-euronews.png'
3Binary files tests/unit/euronews/preview-card-euronews.png 1970-01-01 00:00:00 +0000 and tests/unit/euronews/preview-card-euronews.png 2015-05-20 13:57:15 +0000 differ326Binary files tests/unit/euronews/preview-card-euronews.png 1970-01-01 00:00:00 +0000 and tests/unit/euronews/preview-card-euronews.png 2015-05-20 13:57:15 +0000 differ
=== added directory 'tests/unit/euronews/renderer'
=== added file 'tests/unit/euronews/renderer/carousel.json'
--- tests/unit/euronews/renderer/carousel.json 1970-01-01 00:00:00 +0000
+++ tests/unit/euronews/renderer/carousel.json 2015-05-20 13:57:15 +0000
@@ -0,0 +1,12 @@
1{
2 "schema-version": 1,
3 "template": {
4 "category-layout": "carousel",
5 "card-size": "medium",
6 "overlay": true
7 },
8 "components": {
9 "title": "title",
10 "art": "image"
11 }
12}
013
=== added file 'tests/unit/euronews/renderer/hgrid.json'
--- tests/unit/euronews/renderer/hgrid.json 1970-01-01 00:00:00 +0000
+++ tests/unit/euronews/renderer/hgrid.json 2015-05-20 13:57:15 +0000
@@ -0,0 +1,15 @@
1{
2 "schema-version": 1,
3 "template": {
4 "category-layout": "grid",
5 "card-layout": "horizontal",
6 "card-size": "medium",
7 "collapsed-rows": 0
8 },
9 "components": {
10 "mascot": "image",
11 "title": "title",
12 "subtitle": "subtitle",
13 "summary": "summary"
14 }
15}
016
=== added file 'tests/unit/euronews/renderer/journal.json'
--- tests/unit/euronews/renderer/journal.json 1970-01-01 00:00:00 +0000
+++ tests/unit/euronews/renderer/journal.json 2015-05-20 13:57:15 +0000
@@ -0,0 +1,15 @@
1{
2 "schema-version": 1,
3 "template": {
4 "category-layout": "vertical-journal",
5 "card-layout": "horizontal",
6 "card-size": "medium",
7 "collapsed-rows": 0
8 },
9 "components": {
10 "art": "image",
11 "title": "title",
12 "subtitle": "subtitle",
13 "summary": "summary"
14 }
15}
016
=== added file 'tests/unit/euronews/renderer/large.json'
--- tests/unit/euronews/renderer/large.json 1970-01-01 00:00:00 +0000
+++ tests/unit/euronews/renderer/large.json 2015-05-20 13:57:15 +0000
@@ -0,0 +1,14 @@
1{
2 "schema-version": 1,
3 "template": {
4 "category-layout": "grid",
5 "card-size": "large",
6 "overlay": true,
7 "collapsed-rows": 0
8 },
9 "components": {
10 "art": "image",
11 "title": "title",
12 "subtitle": "subtitle"
13 }
14}
015
=== added file 'tests/unit/euronews/renderer/wide-art.json'
--- tests/unit/euronews/renderer/wide-art.json 1970-01-01 00:00:00 +0000
+++ tests/unit/euronews/renderer/wide-art.json 2015-05-20 13:57:15 +0000
@@ -0,0 +1,13 @@
1{
2 "schema-version": 1,
3 "template": {
4 "category-layout": "grid",
5 "card-size": "large",
6 "overlay": true,
7 "collapsed-rows": 0
8 },
9 "components": {
10 "title": "title",
11 "art": { "field": "image", "aspect-ratio": 2.5 }
12 }
13}
014
=== added file 'tests/unit/euronews/rss-scope.ini.in'
--- tests/unit/euronews/rss-scope.ini.in 1970-01-01 00:00:00 +0000
+++ tests/unit/euronews/rss-scope.ini.in 2015-05-20 13:57:15 +0000
@@ -0,0 +1,12 @@
1[ScopeConfig]
2DisplayName = @SCOPE_TITLE@
3Description = This is an Ubuntu search plugin that enables information from @SCOPE_TITLE@ to be searched and displayed in the Dash. If you do not wish to search this content source, you can disable this search plugin.
4Author = @SCOPE_AUTHOR@
5Art = ./images/@SCOPE_NAME@-art.png
6Icon = @SCOPE_ICON@
7SearchHint = Search @SCOPE_TITLE@
8[Appearance]
9Background=@SCOPE_COLOR@
10PageHeader.Logo=./images/@SCOPE_LOGO@
11PageHeader.Background=@BG_COLOR@
12PageHeader.ForegroundColor=@FG_COLOR@
013
=== added directory 'tests/unit/scope'
=== added file 'tests/unit/scope/test-scope.cpp'
--- tests/unit/scope/test-scope.cpp 1970-01-01 00:00:00 +0000
+++ tests/unit/scope/test-scope.cpp 2015-05-20 13:57:15 +0000
@@ -0,0 +1,630 @@
1/*
2 * Copyright 2015 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authors:
17 * Scott Sweeny
18 */
19
20#include <scope/scope.h>
21
22#include <core/posix/exec.h>
23#include <gtest/gtest.h>
24#include <gmock/gmock.h>
25#include <string>
26#include <unity/scopes/SearchReply.h>
27#include <unity/scopes/SearchReplyProxyFwd.h>
28#include <unity/scopes/Variant.h>
29#include <unity/scopes/testing/Category.h>
30#include <unity/scopes/testing/MockSearchReply.h>
31#include <unity/scopes/testing/TypedScopeFixture.h>
32
33using namespace std;
34using namespace testing;
35using namespace scope;
36
37namespace posix = core::posix;
38namespace sc = unity::scopes;
39namespace sct = unity::scopes::testing;
40
41/**
42 * Keep the tests in an anonymous namespace
43 */
44namespace {
45
46/**
47 * Custom matcher to check the properties of search results
48 */
49MATCHER_P2(ResultProp, prop, value, "") {
50 if (arg.contains(prop)) {
51 *result_listener << "result[" << prop << "] is " << arg[prop].serialize_json();
52 } else {
53 *result_listener << "result[" << prop << "] is not set";
54 }
55 return arg.contains(prop) && arg[prop] == sc::Variant(value);
56}
57
58MATCHER_P2(ResultPropU8, prop, value, "") {
59 return arg.contains(prop) && arg[prop] == value;
60}
61
62/**
63 * Custom matcher to check the presence of departments
64 */
65MATCHER_P(IsDepartment, department, "") {
66 return arg->serialize() == department->serialize();
67}
68
69bool server_started = false;
70
71typedef sct::TypedScopeFixture<Scope> TypedScopeFixtureScope;
72
73class TestScope: public TypedScopeFixtureScope {
74protected:
75 void SetUp() override
76 {
77 // TODO: Fix weirdness with server starting
78 //if (!server_started) {
79 cout << "STARTING SERVER" << endl;
80 // Start up Python-based fake server
81 fake_server_ = posix::exec("/usr/bin/python3", { FAKE_SERVER },
82 // Need to set LANG so that the server
83 // won't choke on UTF-8 files
84 {{"LANG", "en_US.UTF-8"} },
85 posix::StandardStream::stdout);
86
87 // Check it's running
88 //ASSERT_GT(fake_server_.pid(), 0);
89
90 // The server will print out the port it is using
91 string port;
92 fake_server_.cout() >> port;
93 // Check we have a port
94 //ASSERT_FALSE(port.empty());
95
96 server_started = true;
97 //} else {
98 cout << "SERVER ALREADY STARTED" << endl;
99 // }
100 }
101
102 void SetUp(string scope)
103 {
104 // Do the normal SetUp
105 TestScope::SetUp();
106
107 // Then do the parent SetUp with the path for our scope data
108 string dir = string(TEST_SCOPE_DIRECTORY) + '/' + scope;
109 cout << "TEST DIR: " << dir << endl;
110 TypedScopeFixture::set_scope_directory(dir);
111 TypedScopeFixtureScope::SetUp();
112 }
113
114 /**
115 * Start by assuming the server is invalid
116 */
117 posix::ChildProcess fake_server_ = posix::ChildProcess::invalid();
118};
119
120class TestScopeVox : public TestScope {
121protected:
122 void SetUp() override
123 {
124 TestScope::SetUp("vox");
125 }
126};
127
128TEST_F(TestScopeVox, empty_search_string) {
129 const sc::CategoryRenderer renderer;
130 NiceMock<sct::MockSearchReply> reply;
131
132 // Build a query with an empty search string
133 sc::CannedQuery query(SCOPE_NAME, "", "");
134
135 // Expect the News category
136 EXPECT_CALL(reply, register_category("news", "", "", _)).Times(1)
137 .WillOnce(Return(make_shared<sct::Category>("news", "", "", renderer)));
138
139 cout << "TESTING RESULTS";
140 // With two results
141 EXPECT_CALL(reply, push(Matcher<sc::CategorisedResult const&>(AllOf(
142 ResultProp("title", "The New England Patriots' deflated footballs scandal, explained"),
143 ResultProp("art", "https://cdn3.vox-cdn.com/thumbor/3YPNccEVQeXUgjjqUexFC-LFOM0=/0x0:4915x3277/400x267/cdn0.vox-cdn.com/uploads/chorus_image/image/45507798/459836192.0.0.jpg"),
144 ResultProp("published", "2015-01-22T16:20:00-05:00"),
145 ResultProp("author", "Joseph Stromberg"),
146 ResultProp("summary", "\n\n\n\n <p>An NFL investigation has found that 11 of the 12 footballs used by the New England Patriots during the AFC Championship were under-inflated, according to ESPN's Chris Mortensen.</p>\n<p>Why might the Patriots want under-inflated footballs? In theory, it would have made the balls easier for quarterback Tom Brady to hold and for the team's receivers to catch during the game's rainy conditions. Because teams always use their own sets of footballs when they're on offense, this wouldn't have helped their opponents, the Indianapolis Colts. For better or worse, this scandal seems to have been unofficially named Deflate-gate.</p>\n<p>On Thursday, both Patriots coach Bill Belichick and Brady denied any involvement, and the league hasn't made any official comment yet. But if the allegations are true, it could mean serious penalties for the Patriots — possibly including fines and lost draft picks. And given previous instances of cheating by the team, it could further tarnish their legacy, even if they win Super Bowl XLIX, giving Brady and Belichick a fourth ring together.</p>\n<p>Here's what we know so far about the situation.</p>\n<h3>What did the Patriots do?</h3>\n\n<p class=\"caption\">Patriots coach Bill Belichick, on the sideline of the AFC Championship. (Elsa/Getty Images)</p>\n<p>In their game on Sunday, January 18 against the Indianapolis Colts — a game in which the winner would advance to the Super Bowl — the Patriots allegedly let a bit of air out of the footballs they were using on offense.</p>\n<p>Initially, it was reported that after catching an interception in the second quarter, Colts linebacker D'Qwell Jackson noticed the ball was less inflated than usual. On the sidelines, he passed it over to an equipment manager, and it eventually made its way to the team's general manager, then the NFL's director of football operations.</p>\n<p>However, Fox Sports' Jay Glazer has since reported that the Patriots' previous opponent (the Baltimore Ravens) tipped the Colts off to the fact that their balls might be under-inflated before the game, and the NFL was already planning to inspect them.</p>\n<p>In any event, officials checked the balls at halftime, and reportedly found that 11 of the 12 balls the Patriots were using were indeed under-inflated — with about two pounds per square inch less pressure than the minimum 12.5 psi mandated by the league. But we still don't know the full results of the investigation.</p>\n<h3>Why would the Patriots want to under-inflate footballs?</h3>\n\n<p class=\"caption\">Patriots quarterback Tom Brady passes during the first quarter against the Colts. (Jared Wickerham/Getty Images)</p>\n<p>The basic idea is that softer, less fully-inflated footballs are easier to hold and catch.</p>\n<p>Given that the game was played in slick, rainy conditions — and that different footballs are used by each team (more on that below) — this could provide a slight advantage to the Patriots offense, especially for quarterback Tom Brady. <span>Teams use their own sets of balls whenever they're on offense, so it wouldn't have benefitted the Colts.</span></p>\n<p>It might not make a huge difference, but materials scientists and players confirm that letting a bit of air out could make the balls somewhat easier to hold, especially for the quarterback.</p>\n<h3>How could the Patriots have done this?</h3>\n\n<p class=\"caption\">Game balls rest in a sideline bag during a December game. (Brett Carlsen/Getty Images)</p>\n<p>Here's how the NFL's system for game balls works: for each game, each team prepares a set of 12 balls for it to use on offense. Team equipment staff are allowed to scuff up brand-new balls, removing the factory shine, and allowing them to be gripped more easily by their quarterbacks.</p>\n<p>Before the game, these balls are delivered to the officials, who test to see if they're inflated to somewhere between 12.5 and 13.5 pounds per square inch. If they're under-inflated, the officials add some air themselves.</p>\n<p>Then, the balls are kept in a zipped bag on the sidelines. During the game, ball boys occasionally hand fresh balls to the officials, who put them in play.</p>\n<p>It's unclear how or when Patriots staff might have let some of the air out of their set of balls. It'd be extremely risky to do so on the sideline, in full view of the whole stadium, but in theory, they should have been properly inflated just before the game. During press conferences on Thursday, both Belichick and Brady denied any involvement or knowledge of deflating the balls.</p>\n<p>An even bigger mystery is how the officials — who handle the balls before every single play — didn't notice they were under-inflated, when one touch by Jackson caught his attention.</p>\n\n<p class=\"caption\">Umpire Carl Paganelli handles a ball during the game. (Elsa/Getty Images)</p>\n<h3>Could under-inflating the balls have let the Patriots win?</h3>\n<p>Almost certainly not. The Patriots beat the Colts 45 to 7 — an especially dominant win, even for the Patriots.</p>\n<p>Further, they scored mostly by running the ball, an area where under-inflated balls wouldn't make much of a difference.</p>\n<p>People aren't upset because the Patriots may have won this game by under-inflating their balls. They're upset because the Patriots have been remarkably dominant for 15 years — but during that time, have consistently pushed the envelope in terms of rules, and on at least one other occasion, have been caught cheating.</p>\n<p>If the team habitually under-inflates its game balls, it could provide a very real advantage — something that may have, in some cases, been the difference between a loss and a win.</p>\n<h3>Is this the first time the Patriots have been accused of cheating?</h3>\n\n<p class=\"caption\">Bill Belichick. (John Tlumacki/The Boston Globe via Getty Images)</p>\n<p>Nope.</p>\n<p>In 2007, the team was caught illegally filming the New York Jets coaching staff. Having tape of the coaches' hand signals — and being able to match them up with the actual plays run on the field — could provide a big advantage, essentially allowing Belichick and the Patriots' staff to decode opponents' signaling systems. Belichick later admitted that he'd been taping opposing coaching staffs ever since becoming a head coach in 2000, and thought it was permitted by league rules.</p>\n<p>It wasn't, and in response, the NFL fined Belichick $500,000, fined the team $250,000, and stripped the team of its first round draft pick. Around the same time, allegations surfaced that Belichick had also filmed a St. Louis Rams practice right before beating them in Super Bowl XXXVI, but he denied it.</p>\n<p>There have also been all other sorts of unproven allegations of cheating by the Patriots. Most recently, two weeks ago, some Baltimore Ravens felt that the kicking balls they used in their playoff loss to the Patriots (a separate set of game balls used solely for kicking and punting) were under-inflated, which would have made it more difficult to kick long field goals. And during a regular season game this past November, Colts players were reportedly suspicious that the Patriots were using under-inflated balls.</p>\n<p>Even when he's playing within the rules, Belichick — smartly — likes to push the envelope in ways that aren't part of conventional football practice. In the same game against the Ravens, he used unusual formations on several plays, for instance, and Ravens coach John Harbaugh complained that his team didn't have enough time to match up, as mandated by league rules.</p>\n<p>For many fans, all this raises a question: what else have Belichick and the Patriots gotten away with?</p>\n<h3>Is there a name for this new scandal?</h3>\n<p>Alas. Yes. Most people seem to be calling it Deflate-gate, the latest in a string of hundreds of scandals with the \"gate\" suffix tacked on, in an allusion to Watergate.</p>\n<p>It'd be great if we could figure out a more creative way to name our scandals, though, and some people have come up with the more imaginative \"Ballghazi.\" It remains to be seen if it will catch on.</p>\n<h3>What's going to happen next?</h3>\n<p>The NFL has said it's hoping to wrap up the investigation quickly, within a few days. That means the official results will likely be public soon — and the story will become a huge one in the week leading up to Super Bowl XLIX.</p>\n<p>However, this scandal won't impact the Super Bowl directly. Instead, if the Patriots are found guilty, the team or Belichick might have to pay fines, and perhaps give up a draft pick in the upcoming draft, which is in April. The punishments will likely be meted out after the Super Bowl.</p>\n\n<p class=\"caption\">Bill Belichick holds the Lombardi Trophy after Super Bowl XXXVIII. (JEFF HAYNES/AFP/Getty Images)</p>\n<p>The biggest consequence of all this is that, if found guilty, Deflate-gate could tarnish the Patriots' long-term legacy.</p>\n<p>If they win the Super Bowl, it could cement Belichick and Brady's legacy as one of the best coach-quarterback pairings of all time — they'd become one of only two duos to ever win four Super Bowls. But having a second instance of confirmed cheating during that remarkable run might change perceptions of it in the future.</p>\n<hr>\n<h4>Watch: Can the NFL survive its concussion crisis?</h4>"),
147 ResultProp("content", "\n\n\n\n <p>An NFL investigation has found that 11 of the 12 footballs used by the New England Patriots during the AFC Championship were under-inflated, according to ESPN's Chris Mortensen.</p>\n<p>Why might the Patriots want under-inflated footballs? In theory, it would have made the balls easier for quarterback Tom Brady to hold and for the team's receivers to catch during the game's rainy conditions. Because teams always use their own sets of footballs when they're on offense, this wouldn't have helped their opponents, the Indianapolis Colts. For better or worse, this scandal seems to have been unofficially named Deflate-gate.</p>\n<p>On Thursday, both Patriots coach Bill Belichick and Brady denied any involvement, and the league hasn't made any official comment yet. But if the allegations are true, it could mean serious penalties for the Patriots — possibly including fines and lost draft picks. And given previous instances of cheating by the team, it could further tarnish their legacy, even if they win Super Bowl XLIX, giving Brady and Belichick a fourth ring together.</p>\n<p>Here's what we know so far about the situation.</p>\n<h3>What did the Patriots do?</h3>\n\n<p class=\"caption\">Patriots coach Bill Belichick, on the sideline of the AFC Championship. (Elsa/Getty Images)</p>\n<p>In their game on Sunday, January 18 against the Indianapolis Colts — a game in which the winner would advance to the Super Bowl — the Patriots allegedly let a bit of air out of the footballs they were using on offense.</p>\n<p>Initially, it was reported that after catching an interception in the second quarter, Colts linebacker D'Qwell Jackson noticed the ball was less inflated than usual. On the sidelines, he passed it over to an equipment manager, and it eventually made its way to the team's general manager, then the NFL's director of football operations.</p>\n<p>However, Fox Sports' Jay Glazer has since reported that the Patriots' previous opponent (the Baltimore Ravens) tipped the Colts off to the fact that their balls might be under-inflated before the game, and the NFL was already planning to inspect them.</p>\n<p>In any event, officials checked the balls at halftime, and reportedly found that 11 of the 12 balls the Patriots were using were indeed under-inflated — with about two pounds per square inch less pressure than the minimum 12.5 psi mandated by the league. But we still don't know the full results of the investigation.</p>\n<h3>Why would the Patriots want to under-inflate footballs?</h3>\n\n<p class=\"caption\">Patriots quarterback Tom Brady passes during the first quarter against the Colts. (Jared Wickerham/Getty Images)</p>\n<p>The basic idea is that softer, less fully-inflated footballs are easier to hold and catch.</p>\n<p>Given that the game was played in slick, rainy conditions — and that different footballs are used by each team (more on that below) — this could provide a slight advantage to the Patriots offense, especially for quarterback Tom Brady. <span>Teams use their own sets of balls whenever they're on offense, so it wouldn't have benefitted the Colts.</span></p>\n<p>It might not make a huge difference, but materials scientists and players confirm that letting a bit of air out could make the balls somewhat easier to hold, especially for the quarterback.</p>\n<h3>How could the Patriots have done this?</h3>\n\n<p class=\"caption\">Game balls rest in a sideline bag during a December game. (Brett Carlsen/Getty Images)</p>\n<p>Here's how the NFL's system for game balls works: for each game, each team prepares a set of 12 balls for it to use on offense. Team equipment staff are allowed to scuff up brand-new balls, removing the factory shine, and allowing them to be gripped more easily by their quarterbacks.</p>\n<p>Before the game, these balls are delivered to the officials, who test to see if they're inflated to somewhere between 12.5 and 13.5 pounds per square inch. If they're under-inflated, the officials add some air themselves.</p>\n<p>Then, the balls are kept in a zipped bag on the sidelines. During the game, ball boys occasionally hand fresh balls to the officials, who put them in play.</p>\n<p>It's unclear how or when Patriots staff might have let some of the air out of their set of balls. It'd be extremely risky to do so on the sideline, in full view of the whole stadium, but in theory, they should have been properly inflated just before the game. During press conferences on Thursday, both Belichick and Brady denied any involvement or knowledge of deflating the balls.</p>\n<p>An even bigger mystery is how the officials — who handle the balls before every single play — didn't notice they were under-inflated, when one touch by Jackson caught his attention.</p>\n\n<p class=\"caption\">Umpire Carl Paganelli handles a ball during the game. (Elsa/Getty Images)</p>\n<h3>Could under-inflating the balls have let the Patriots win?</h3>\n<p>Almost certainly not. The Patriots beat the Colts 45 to 7 — an especially dominant win, even for the Patriots.</p>\n<p>Further, they scored mostly by running the ball, an area where under-inflated balls wouldn't make much of a difference.</p>\n<p>People aren't upset because the Patriots may have won this game by under-inflating their balls. They're upset because the Patriots have been remarkably dominant for 15 years — but during that time, have consistently pushed the envelope in terms of rules, and on at least one other occasion, have been caught cheating.</p>\n<p>If the team habitually under-inflates its game balls, it could provide a very real advantage — something that may have, in some cases, been the difference between a loss and a win.</p>\n<h3>Is this the first time the Patriots have been accused of cheating?</h3>\n\n<p class=\"caption\">Bill Belichick. (John Tlumacki/The Boston Globe via Getty Images)</p>\n<p>Nope.</p>\n<p>In 2007, the team was caught illegally filming the New York Jets coaching staff. Having tape of the coaches' hand signals — and being able to match them up with the actual plays run on the field — could provide a big advantage, essentially allowing Belichick and the Patriots' staff to decode opponents' signaling systems. Belichick later admitted that he'd been taping opposing coaching staffs ever since becoming a head coach in 2000, and thought it was permitted by league rules.</p>\n<p>It wasn't, and in response, the NFL fined Belichick $500,000, fined the team $250,000, and stripped the team of its first round draft pick. Around the same time, allegations surfaced that Belichick had also filmed a St. Louis Rams practice right before beating them in Super Bowl XXXVI, but he denied it.</p>\n<p>There have also been all other sorts of unproven allegations of cheating by the Patriots. Most recently, two weeks ago, some Baltimore Ravens felt that the kicking balls they used in their playoff loss to the Patriots (a separate set of game balls used solely for kicking and punting) were under-inflated, which would have made it more difficult to kick long field goals. And during a regular season game this past November, Colts players were reportedly suspicious that the Patriots were using under-inflated balls.</p>\n<p>Even when he's playing within the rules, Belichick — smartly — likes to push the envelope in ways that aren't part of conventional football practice. In the same game against the Ravens, he used unusual formations on several plays, for instance, and Ravens coach John Harbaugh complained that his team didn't have enough time to match up, as mandated by league rules.</p>\n<p>For many fans, all this raises a question: what else have Belichick and the Patriots gotten away with?</p>\n<h3>Is there a name for this new scandal?</h3>\n<p>Alas. Yes. Most people seem to be calling it Deflate-gate, the latest in a string of hundreds of scandals with the \"gate\" suffix tacked on, in an allusion to Watergate.</p>\n<p>It'd be great if we could figure out a more creative way to name our scandals, though, and some people have come up with the more imaginative \"Ballghazi.\" It remains to be seen if it will catch on.</p>\n<h3>What's going to happen next?</h3>\n<p>The NFL has said it's hoping to wrap up the investigation quickly, within a few days. That means the official results will likely be public soon — and the story will become a huge one in the week leading up to Super Bowl XLIX.</p>\n<p>However, this scandal won't impact the Super Bowl directly. Instead, if the Patriots are found guilty, the team or Belichick might have to pay fines, and perhaps give up a draft pick in the upcoming draft, which is in April. The punishments will likely be meted out after the Super Bowl.</p>\n\n<p class=\"caption\">Bill Belichick holds the Lombardi Trophy after Super Bowl XXXVIII. (JEFF HAYNES/AFP/Getty Images)</p>\n<p>The biggest consequence of all this is that, if found guilty, Deflate-gate could tarnish the Patriots' long-term legacy.</p>\n<p>If they win the Super Bowl, it could cement Belichick and Brady's legacy as one of the best coach-quarterback pairings of all time — they'd become one of only two duos to ever win four Super Bowls. But having a second instance of confirmed cheating during that remarkable run might change perceptions of it in the future.</p>\n<hr>\n<h4>Watch: Can the NFL survive its concussion crisis?</h4>")
148 )))).WillOnce(Return(true));
149 EXPECT_CALL(reply, push(Matcher<sc::CategorisedResult const&>(AllOf(
150 ResultProp("title", "Read McDonald's workers' shocking harassment and discrimination complaints — and why they're so important"),
151 ResultProp("art", "https://cdn2.vox-cdn.com/thumbor/3YAMFCiMs4zJnJIty3Fl402tGhY=/0x40:2039x1399/400x267/cdn0.vox-cdn.com/uploads/chorus_image/image/45516554/112561118.0.jpg"),
152 ResultProp("published", "2015-01-22T15:40:02-05:00"),
153 ResultProp("author", "Danielle Kurtzleben"),
154 ResultProp("summary", "\n\n\n\n <p>Ten current and former McDonald's workers filed suit in a Virginia district court on Thursday, alleging racial discrimination and sexual harassment at McDonald's locations in two Virginia cities.</p>\n<p>In one store, for example, one supervisor allegedly would say it was \"too dark in the store\" at times when most workers were African-American. And the suit goes on to list some almost unfathomably degrading behavior on the part of supervisors:</p>\n<blockquote>\n<p>Plaintiffs were subjected to rampant racial and sexual harassment, committed by the restaurants' highest-ranking supervisors. Together, these supervisors demeaned African American workers; often complained that \"there are too many black people in the store;\" called African-American workers \"bitch,\" \"ghetto,\" and \"ratchet;\" called Hispanic workers \"dirty Mexican;\" disciplined African-American employees for rule infractions that were forgiven when committed by white employees; inappropriately touched female employees on their legs and buttocks; sent female employees sexual pictures; and solicited sexual relations from female employees.</p>\n</blockquote>\n<p>The allegations in the lawsuit are of course shocking on a basic level. But this suit is also important in a much subtler way, in that it's filed against both Soweva — the franchisee operating these stores — and the McDonald's corporation itself. Far more than being a simply discrimination and harassment suit, this case is another example of a question that has repeatedly been raised in labor law in the last year — when is an big chain a \"joint employer\" of people who work for one of its franchises?</p>\n<p>In other words, can McDonald's and other corporations be held legally accountable for the working conditions endured by front-line employees who wear their uniforms but are technically employees of independently owned franchises? This seemingly pedantic question actually has broad implications for many franchise-heavy industries (fast food, hotels, gyms) and how they relate to their workers — how they schedule employees and negotiate with unions, for example.</p>\n<h3>A bigger, nationwide debate</h3>\n<p>The franchising debate has heated up with a few high-profile cases. In California, for example, the supreme court last year ultimately ruled in favor of Domino's Pizza, saying it was not a joint employer along with its franchise operators. A yet-to-be-decided case before the National Labor Relations Board questions whether a waste management company is an employer along with its subcontractors. And in December, the NLRB decided to authorize complaints against both franchise operators and the McDonald's parent company, alleging retaliation against employees who participated in protests demanding $15-per-hour wages. Even though that was a preliminary decision, it was considered a big win for labor-rights advocates.</p>\n<p>These sorts of cases could strike at the heart of the franchisor-franchisee relationship, in which the franchisee runs the business according to certain specifications set by the parent company but operates independently in many other ways, like in how it treats its employees. That often means a franchisee acts as a sort of buffer between workers and the parent corporation.</p>\n<p>But the question of joint employership is being reconsidered lately. The NLRB, for example, appears willing to reconsider that definition, which currently says an employer must have \"direct and immediate impact\" on the terms and conditions of workers' employment — for example, having a say in hiring and firing, as well as wage-setting.</p>\n<p>In this case, plaintiffs are saying that McDonald's is partially liable because it had so much control over its stores. The lawsuit references McDonald's' detailed training manuals, control over menus, and routine visits from McDonald's mystery shoppers as examples of the parent company's control over stores. And in a call with reporters, plaintiff Katrina Stanfield said she complained to McDonald's about the harassment and discrimination and that they did nothing in response.</p>\n<h3>The repercussions of a new definition could be huge</h3>\n<p>According to one attorney, when the definition is murky, it makes operating those businesses difficult.</p>\n<p>\"If you don't know who the employer is, you can't allocate liability, and you really don't know how to run your business,\" says Michael Lotito, co-chair of the Workplace Policy Institute at law firm Littler Mendelson.</p>\n<p>And if pending cases do indeed find parent companies to be liable for their franchisees' wrongdoings, it could have repercussions far beyond McDonald's. <span>And the broader question of what, exactly, is an \"employer\" could even affect the relationships between, for example, retailers and suppliers, as well as employers and staffing agencies. </span><span>Of course, neither the NLRB nor Virginia's District Court has the last word. Settling this question could be a years-long process, says Lotito, and decisions could differ from jurisdiction to jurisdiction. And given that groups like SEIU and Fast Food Forward are fighting hard on this question, expect to hear more about the joint employer issue in the years to come.</span></p>"),
155 ResultProp("content", "\n\n\n\n <p>Ten current and former McDonald's workers filed suit in a Virginia district court on Thursday, alleging racial discrimination and sexual harassment at McDonald's locations in two Virginia cities.</p>\n<p>In one store, for example, one supervisor allegedly would say it was \"too dark in the store\" at times when most workers were African-American. And the suit goes on to list some almost unfathomably degrading behavior on the part of supervisors:</p>\n<blockquote>\n<p>Plaintiffs were subjected to rampant racial and sexual harassment, committed by the restaurants' highest-ranking supervisors. Together, these supervisors demeaned African American workers; often complained that \"there are too many black people in the store;\" called African-American workers \"bitch,\" \"ghetto,\" and \"ratchet;\" called Hispanic workers \"dirty Mexican;\" disciplined African-American employees for rule infractions that were forgiven when committed by white employees; inappropriately touched female employees on their legs and buttocks; sent female employees sexual pictures; and solicited sexual relations from female employees.</p>\n</blockquote>\n<p>The allegations in the lawsuit are of course shocking on a basic level. But this suit is also important in a much subtler way, in that it's filed against both Soweva — the franchisee operating these stores — and the McDonald's corporation itself. Far more than being a simply discrimination and harassment suit, this case is another example of a question that has repeatedly been raised in labor law in the last year — when is an big chain a \"joint employer\" of people who work for one of its franchises?</p>\n<p>In other words, can McDonald's and other corporations be held legally accountable for the working conditions endured by front-line employees who wear their uniforms but are technically employees of independently owned franchises? This seemingly pedantic question actually has broad implications for many franchise-heavy industries (fast food, hotels, gyms) and how they relate to their workers — how they schedule employees and negotiate with unions, for example.</p>\n<h3>A bigger, nationwide debate</h3>\n<p>The franchising debate has heated up with a few high-profile cases. In California, for example, the supreme court last year ultimately ruled in favor of Domino's Pizza, saying it was not a joint employer along with its franchise operators. A yet-to-be-decided case before the National Labor Relations Board questions whether a waste management company is an employer along with its subcontractors. And in December, the NLRB decided to authorize complaints against both franchise operators and the McDonald's parent company, alleging retaliation against employees who participated in protests demanding $15-per-hour wages. Even though that was a preliminary decision, it was considered a big win for labor-rights advocates.</p>\n<p>These sorts of cases could strike at the heart of the franchisor-franchisee relationship, in which the franchisee runs the business according to certain specifications set by the parent company but operates independently in many other ways, like in how it treats its employees. That often means a franchisee acts as a sort of buffer between workers and the parent corporation.</p>\n<p>But the question of joint employership is being reconsidered lately. The NLRB, for example, appears willing to reconsider that definition, which currently says an employer must have \"direct and immediate impact\" on the terms and conditions of workers' employment — for example, having a say in hiring and firing, as well as wage-setting.</p>\n<p>In this case, plaintiffs are saying that McDonald's is partially liable because it had so much control over its stores. The lawsuit references McDonald's' detailed training manuals, control over menus, and routine visits from McDonald's mystery shoppers as examples of the parent company's control over stores. And in a call with reporters, plaintiff Katrina Stanfield said she complained to McDonald's about the harassment and discrimination and that they did nothing in response.</p>\n<h3>The repercussions of a new definition could be huge</h3>\n<p>According to one attorney, when the definition is murky, it makes operating those businesses difficult.</p>\n<p>\"If you don't know who the employer is, you can't allocate liability, and you really don't know how to run your business,\" says Michael Lotito, co-chair of the Workplace Policy Institute at law firm Littler Mendelson.</p>\n<p>And if pending cases do indeed find parent companies to be liable for their franchisees' wrongdoings, it could have repercussions far beyond McDonald's. <span>And the broader question of what, exactly, is an \"employer\" could even affect the relationships between, for example, retailers and suppliers, as well as employers and staffing agencies. </span><span>Of course, neither the NLRB nor Virginia's District Court has the last word. Settling this question could be a years-long process, says Lotito, and decisions could differ from jurisdiction to jurisdiction. And given that groups like SEIU and Fast Food Forward are fighting hard on this question, expect to hear more about the joint employer issue in the years to come.</span></p>")
156 )))).WillOnce(Return(true));
157
158 sc::SearchReplyProxy reply_proxy(&reply, [](sc::SearchReply*) {}); // note: this is a std::shared_ptr with empty deleter
159 sc::SearchMetadata meta_data("en_EN", "phone");
160
161 // Create a query object
162 auto search_query = scope->search(query, meta_data);
163 ASSERT_NE(nullptr, search_query);
164
165 // Run the search
166 search_query->run(reply_proxy);
167
168 // Google Mock will make assertions when the mocks are destructed.
169}
170
171TEST_F(TestScopeVox, search) {
172 const sc::CategoryRenderer renderer;
173 NiceMock<sct::MockSearchReply> reply;
174
175 // Build a query with a non-empty search string
176 sc::CannedQuery query(SCOPE_NAME, "worker", "");
177
178 // Expect the current weather category
179 EXPECT_CALL(reply, register_category("news", "", "", _)).Times(1)
180 .WillOnce(Return(make_shared<sct::Category>("news", "", "", renderer)));
181
182 // With one result
183 EXPECT_CALL(reply, push(Matcher<sc::CategorisedResult const&>(AllOf(
184 ResultProp("title", "Read McDonald's workers' shocking harassment and discrimination complaints — and why they're so important"),
185 ResultProp("art", "https://cdn2.vox-cdn.com/thumbor/3YAMFCiMs4zJnJIty3Fl402tGhY=/0x40:2039x1399/400x267/cdn0.vox-cdn.com/uploads/chorus_image/image/45516554/112561118.0.jpg"),
186 ResultProp("published", "2015-01-22T15:40:02-05:00"),
187 ResultProp("author", "Danielle Kurtzleben"),
188 ResultProp("summary", "\n\n\n\n <p>Ten current and former McDonald's workers filed suit in a Virginia district court on Thursday, alleging racial discrimination and sexual harassment at McDonald's locations in two Virginia cities.</p>\n<p>In one store, for example, one supervisor allegedly would say it was \"too dark in the store\" at times when most workers were African-American. And the suit goes on to list some almost unfathomably degrading behavior on the part of supervisors:</p>\n<blockquote>\n<p>Plaintiffs were subjected to rampant racial and sexual harassment, committed by the restaurants' highest-ranking supervisors. Together, these supervisors demeaned African American workers; often complained that \"there are too many black people in the store;\" called African-American workers \"bitch,\" \"ghetto,\" and \"ratchet;\" called Hispanic workers \"dirty Mexican;\" disciplined African-American employees for rule infractions that were forgiven when committed by white employees; inappropriately touched female employees on their legs and buttocks; sent female employees sexual pictures; and solicited sexual relations from female employees.</p>\n</blockquote>\n<p>The allegations in the lawsuit are of course shocking on a basic level. But this suit is also important in a much subtler way, in that it's filed against both Soweva — the franchisee operating these stores — and the McDonald's corporation itself. Far more than being a simply discrimination and harassment suit, this case is another example of a question that has repeatedly been raised in labor law in the last year — when is an big chain a \"joint employer\" of people who work for one of its franchises?</p>\n<p>In other words, can McDonald's and other corporations be held legally accountable for the working conditions endured by front-line employees who wear their uniforms but are technically employees of independently owned franchises? This seemingly pedantic question actually has broad implications for many franchise-heavy industries (fast food, hotels, gyms) and how they relate to their workers — how they schedule employees and negotiate with unions, for example.</p>\n<h3>A bigger, nationwide debate</h3>\n<p>The franchising debate has heated up with a few high-profile cases. In California, for example, the supreme court last year ultimately ruled in favor of Domino's Pizza, saying it was not a joint employer along with its franchise operators. A yet-to-be-decided case before the National Labor Relations Board questions whether a waste management company is an employer along with its subcontractors. And in December, the NLRB decided to authorize complaints against both franchise operators and the McDonald's parent company, alleging retaliation against employees who participated in protests demanding $15-per-hour wages. Even though that was a preliminary decision, it was considered a big win for labor-rights advocates.</p>\n<p>These sorts of cases could strike at the heart of the franchisor-franchisee relationship, in which the franchisee runs the business according to certain specifications set by the parent company but operates independently in many other ways, like in how it treats its employees. That often means a franchisee acts as a sort of buffer between workers and the parent corporation.</p>\n<p>But the question of joint employership is being reconsidered lately. The NLRB, for example, appears willing to reconsider that definition, which currently says an employer must have \"direct and immediate impact\" on the terms and conditions of workers' employment — for example, having a say in hiring and firing, as well as wage-setting.</p>\n<p>In this case, plaintiffs are saying that McDonald's is partially liable because it had so much control over its stores. The lawsuit references McDonald's' detailed training manuals, control over menus, and routine visits from McDonald's mystery shoppers as examples of the parent company's control over stores. And in a call with reporters, plaintiff Katrina Stanfield said she complained to McDonald's about the harassment and discrimination and that they did nothing in response.</p>\n<h3>The repercussions of a new definition could be huge</h3>\n<p>According to one attorney, when the definition is murky, it makes operating those businesses difficult.</p>\n<p>\"If you don't know who the employer is, you can't allocate liability, and you really don't know how to run your business,\" says Michael Lotito, co-chair of the Workplace Policy Institute at law firm Littler Mendelson.</p>\n<p>And if pending cases do indeed find parent companies to be liable for their franchisees' wrongdoings, it could have repercussions far beyond McDonald's. <span>And the broader question of what, exactly, is an \"employer\" could even affect the relationships between, for example, retailers and suppliers, as well as employers and staffing agencies. </span><span>Of course, neither the NLRB nor Virginia's District Court has the last word. Settling this question could be a years-long process, says Lotito, and decisions could differ from jurisdiction to jurisdiction. And given that groups like SEIU and Fast Food Forward are fighting hard on this question, expect to hear more about the joint employer issue in the years to come.</span></p>"),
189 ResultProp("content", "\n\n\n\n <p>Ten current and former McDonald's workers filed suit in a Virginia district court on Thursday, alleging racial discrimination and sexual harassment at McDonald's locations in two Virginia cities.</p>\n<p>In one store, for example, one supervisor allegedly would say it was \"too dark in the store\" at times when most workers were African-American. And the suit goes on to list some almost unfathomably degrading behavior on the part of supervisors:</p>\n<blockquote>\n<p>Plaintiffs were subjected to rampant racial and sexual harassment, committed by the restaurants' highest-ranking supervisors. Together, these supervisors demeaned African American workers; often complained that \"there are too many black people in the store;\" called African-American workers \"bitch,\" \"ghetto,\" and \"ratchet;\" called Hispanic workers \"dirty Mexican;\" disciplined African-American employees for rule infractions that were forgiven when committed by white employees; inappropriately touched female employees on their legs and buttocks; sent female employees sexual pictures; and solicited sexual relations from female employees.</p>\n</blockquote>\n<p>The allegations in the lawsuit are of course shocking on a basic level. But this suit is also important in a much subtler way, in that it's filed against both Soweva — the franchisee operating these stores — and the McDonald's corporation itself. Far more than being a simply discrimination and harassment suit, this case is another example of a question that has repeatedly been raised in labor law in the last year — when is an big chain a \"joint employer\" of people who work for one of its franchises?</p>\n<p>In other words, can McDonald's and other corporations be held legally accountable for the working conditions endured by front-line employees who wear their uniforms but are technically employees of independently owned franchises? This seemingly pedantic question actually has broad implications for many franchise-heavy industries (fast food, hotels, gyms) and how they relate to their workers — how they schedule employees and negotiate with unions, for example.</p>\n<h3>A bigger, nationwide debate</h3>\n<p>The franchising debate has heated up with a few high-profile cases. In California, for example, the supreme court last year ultimately ruled in favor of Domino's Pizza, saying it was not a joint employer along with its franchise operators. A yet-to-be-decided case before the National Labor Relations Board questions whether a waste management company is an employer along with its subcontractors. And in December, the NLRB decided to authorize complaints against both franchise operators and the McDonald's parent company, alleging retaliation against employees who participated in protests demanding $15-per-hour wages. Even though that was a preliminary decision, it was considered a big win for labor-rights advocates.</p>\n<p>These sorts of cases could strike at the heart of the franchisor-franchisee relationship, in which the franchisee runs the business according to certain specifications set by the parent company but operates independently in many other ways, like in how it treats its employees. That often means a franchisee acts as a sort of buffer between workers and the parent corporation.</p>\n<p>But the question of joint employership is being reconsidered lately. The NLRB, for example, appears willing to reconsider that definition, which currently says an employer must have \"direct and immediate impact\" on the terms and conditions of workers' employment — for example, having a say in hiring and firing, as well as wage-setting.</p>\n<p>In this case, plaintiffs are saying that McDonald's is partially liable because it had so much control over its stores. The lawsuit references McDonald's' detailed training manuals, control over menus, and routine visits from McDonald's mystery shoppers as examples of the parent company's control over stores. And in a call with reporters, plaintiff Katrina Stanfield said she complained to McDonald's about the harassment and discrimination and that they did nothing in response.</p>\n<h3>The repercussions of a new definition could be huge</h3>\n<p>According to one attorney, when the definition is murky, it makes operating those businesses difficult.</p>\n<p>\"If you don't know who the employer is, you can't allocate liability, and you really don't know how to run your business,\" says Michael Lotito, co-chair of the Workplace Policy Institute at law firm Littler Mendelson.</p>\n<p>And if pending cases do indeed find parent companies to be liable for their franchisees' wrongdoings, it could have repercussions far beyond McDonald's. <span>And the broader question of what, exactly, is an \"employer\" could even affect the relationships between, for example, retailers and suppliers, as well as employers and staffing agencies. </span><span>Of course, neither the NLRB nor Virginia's District Court has the last word. Settling this question could be a years-long process, says Lotito, and decisions could differ from jurisdiction to jurisdiction. And given that groups like SEIU and Fast Food Forward are fighting hard on this question, expect to hear more about the joint employer issue in the years to come.</span></p>")
190 )))).WillOnce(Return(true));
191
192
193 sc::SearchReplyProxy reply_proxy(&reply, [](sc::SearchReply*) {}); // note: this is a std::shared_ptr with empty deleter
194 sc::SearchMetadata meta_data("en_EN", "phone");
195
196 // Create a query object
197 auto search_query = scope->search(query, meta_data);
198 ASSERT_NE(nullptr, search_query);
199
200 // Run the search
201 search_query->run(reply_proxy);
202
203 // Google Mock will make assertions when the mocks are destructed.
204}
205
206class TestScopeBBC : public TestScope {
207protected:
208 void SetUp() override
209 {
210 TestScope::SetUp("bbc");
211 }
212};
213
214TEST_F(TestScopeBBC, empty_search_string) {
215 const sc::CategoryRenderer renderer;
216 NiceMock<sct::MockSearchReply> reply;
217
218 // Build a query with an empty search string
219 sc::CannedQuery query(SCOPE_NAME, "", "");
220
221 // Expect the News category
222 EXPECT_CALL(reply, register_category("news", "", "", _)).Times(1)
223 .WillOnce(Return(make_shared<sct::Category>("news", "", "", renderer)));
224
225 cout << "TESTING RESULTS";
226 // With two results
227 EXPECT_CALL(reply, push(Matcher<sc::CategorisedResult const&>(AllOf(
228 ResultProp("title", "Dewani cleared of honeymoon murder"),
229 ResultProp("art", "http://news.bbcimg.co.uk/media/images/79581000/jpg/_79581909_78423657.jpg"),
230 ResultProp("published", "Mon, 08 Dec 2014 14:40:30 GMT"),
231 ResultProp("summary", "The family of Anni Dewani believe they have been failed by the justice system after millionaire businessman Shrien Dewani is cleared of the honeymoon murder."),
232 ResultProp("content", "The family of Anni Dewani believe they have been failed by the justice system after millionaire businessman Shrien Dewani is cleared of the honeymoon murder.")
233 )))).WillOnce(Return(true));
234 EXPECT_CALL(reply, push(Matcher<sc::CategorisedResult const&>(AllOf(
235 ResultProp("title", "'Pay benefits faster' to cut hunger"),
236 ResultProp("art", "http://news.bbcimg.co.uk/media/images/79569000/jpg/_79569924_79569916.jpg"),
237 ResultProp("published", "Mon, 08 Dec 2014 10:56:04 GMT"),
238 ResultProp("summary", "An income squeeze, benefit delays and high utility bills are blamed by a cross-party committee of MPs for a rise in hunger in the UK."),
239 ResultProp("content", "An income squeeze, benefit delays and high utility bills are blamed by a cross-party committee of MPs for a rise in hunger in the UK.")
240 )))).WillOnce(Return(true));
241
242 sc::SearchReplyProxy reply_proxy(&reply, [](sc::SearchReply*) {}); // note: this is a std::shared_ptr with empty deleter
243 sc::SearchMetadata meta_data("en_EN", "phone");
244
245 // Create a query object
246 auto search_query = scope->search(query, meta_data);
247 ASSERT_NE(nullptr, search_query);
248
249 // Run the search
250 search_query->run(reply_proxy);
251
252 // Google Mock will make assertions when the mocks are destructed.
253}
254
255TEST_F(TestScopeBBC, search) {
256 const sc::CategoryRenderer renderer;
257 NiceMock<sct::MockSearchReply> reply;
258
259 // Build a query with a non-empty search string
260 sc::CannedQuery query(SCOPE_NAME, "hunger", "");
261
262 // Expect the current weather category
263 EXPECT_CALL(reply, register_category("news", "", "", _)).Times(1)
264 .WillOnce(Return(make_shared<sct::Category>("news", "", "", renderer)));
265
266 // With one result
267 EXPECT_CALL(reply, push(Matcher<sc::CategorisedResult const&>(AllOf(
268 ResultProp("title", "'Pay benefits faster' to cut hunger"),
269 ResultProp("art", "http://news.bbcimg.co.uk/media/images/79569000/jpg/_79569924_79569916.jpg"),
270 ResultProp("published", "Mon, 08 Dec 2014 10:56:04 GMT"),
271 ResultProp("summary", "An income squeeze, benefit delays and high utility bills are blamed by a cross-party committee of MPs for a rise in hunger in the UK."),
272 ResultProp("content", "An income squeeze, benefit delays and high utility bills are blamed by a cross-party committee of MPs for a rise in hunger in the UK.")
273 )))).WillOnce(Return(true));
274
275
276 sc::SearchReplyProxy reply_proxy(&reply, [](sc::SearchReply*) {}); // note: this is a std::shared_ptr with empty deleter
277 sc::SearchMetadata meta_data("en_EN", "phone");
278
279 // Create a query object
280 auto search_query = scope->search(query, meta_data);
281 ASSERT_NE(nullptr, search_query);
282
283 // Run the search
284 search_query->run(reply_proxy);
285
286 // Google Mock will make assertions when the mocks are destructed.
287}
288
289class TestScopeCnet : public TestScope {
290protected:
291 void SetUp() override
292 {
293 TestScope::SetUp("cnet");
294 }
295};
296
297TEST_F(TestScopeCnet, empty_search_string) {
298 const sc::CategoryRenderer renderer;
299 NiceMock<sct::MockSearchReply> reply;
300
301 // Build a query with an empty search string
302 sc::CannedQuery query(SCOPE_NAME, "", "");
303
304 // Expect the News category
305 EXPECT_CALL(reply, register_category("news", "", "", _)).Times(1)
306 .WillOnce(Return(make_shared<sct::Category>("news", "", "", renderer)));
307
308 cout << "TESTING RESULTS";
309 // With two results
310 EXPECT_CALL(reply, push(Matcher<sc::CategorisedResult const&>(AllOf(
311 ResultProp("title", "Cook with gas like a pro on the hardy Decor Renaissance range"),
312 ResultProp("art", "http://cnet3.cbsistatic.com/hub/i/r/2015/01/22/cf096def-ba6c-4fed-a624-5789eaa42cc1/thumbnail/300x230/84411a75f4fa59904efffe0cb1e9b371/fldacorrenaissanceprostylegasrange0.jpg"),
313 ResultProp("published", "Thu, 22 Jan 2015 14:52:46 GMT"),
314 ResultProp("author", "Brian Bennett"),
315 ResultProp("summary", "Dacor's new gas grilling monster is built to last and cook with lots of control."),
316 ResultProp("content", "Dacor's new gas grilling monster is built to last and cook with lots of control.")
317 )))).WillOnce(Return(true));
318 EXPECT_CALL(reply, push(Matcher<sc::CategorisedResult const&>(AllOf(
319 ResultProp("title", "Dropbox app arrives on Windows tablets, phones"),
320 ResultProp("art", "http://cnet3.cbsistatic.com/hub/i/r/2015/01/22/8ea8815f-4595-4184-a65f-6a494ea16e00/thumbnail/300x230/21ab57c0ba05d8ceb5dcf00a468e63e8/dropbox-windows-app.jpg"),
321 ResultProp("published", "Thu, 22 Jan 2015 14:45:36 GMT"),
322 ResultProp("author", "Lance Whitney"),
323 ResultProp("summary", "Dropbox, Microsoft hope to win over more customers with improved work flow and compatibilty."),
324 ResultProp("content", "Dropbox, Microsoft hope to win over more customers with improved work flow and compatibilty.")
325 )))).WillOnce(Return(true));
326
327 sc::SearchReplyProxy reply_proxy(&reply, [](sc::SearchReply*) {}); // note: this is a std::shared_ptr with empty deleter
328 sc::SearchMetadata meta_data("en_EN", "phone");
329
330 // Create a query object
331 auto search_query = scope->search(query, meta_data);
332 ASSERT_NE(nullptr, search_query);
333
334 // Run the search
335 search_query->run(reply_proxy);
336
337 // Google Mock will make assertions when the mocks are destructed.
338}
339
340TEST_F(TestScopeCnet, search) {
341 const sc::CategoryRenderer renderer;
342 NiceMock<sct::MockSearchReply> reply;
343
344 // Build a query with a non-empty search string
345 sc::CannedQuery query(SCOPE_NAME, "gas", "");
346
347 // Expect the current weather category
348 EXPECT_CALL(reply, register_category("news", "", "", _)).Times(1)
349 .WillOnce(Return(make_shared<sct::Category>("news", "", "", renderer)));
350
351 // With one result
352 EXPECT_CALL(reply, push(Matcher<sc::CategorisedResult const&>(AllOf(
353 ResultProp("title", "Cook with gas like a pro on the hardy Decor Renaissance range"),
354 ResultProp("art", "http://cnet3.cbsistatic.com/hub/i/r/2015/01/22/cf096def-ba6c-4fed-a624-5789eaa42cc1/thumbnail/300x230/84411a75f4fa59904efffe0cb1e9b371/fldacorrenaissanceprostylegasrange0.jpg"),
355 ResultProp("published", "Thu, 22 Jan 2015 14:52:46 GMT"),
356 ResultProp("author", "Brian Bennett"),
357 ResultProp("summary", "Dacor's new gas grilling monster is built to last and cook with lots of control."),
358 ResultProp("content", "Dacor's new gas grilling monster is built to last and cook with lots of control.")
359 )))).WillOnce(Return(true));
360
361 sc::SearchReplyProxy reply_proxy(&reply, [](sc::SearchReply*) {}); // note: this is a std::shared_ptr with empty deleter
362 sc::SearchMetadata meta_data("en_EN", "phone");
363
364 // Create a query object
365 auto search_query = scope->search(query, meta_data);
366 ASSERT_NE(nullptr, search_query);
367
368 // Run the search
369 search_query->run(reply_proxy);
370
371 // Google Mock will make assertions when the mocks are destructed.
372}
373
374class TestScopeEuronews : public TestScope {
375protected:
376 void SetUp() override
377 {
378 TestScope::SetUp("euronews");
379 }
380};
381
382TEST_F(TestScopeEuronews, empty_search_string) {
383 const sc::CategoryRenderer renderer;
384 NiceMock<sct::MockSearchReply> reply;
385
386 // Build a query with an empty search string
387 sc::CannedQuery query(SCOPE_NAME, "", "");
388
389 // Expect the News category
390 EXPECT_CALL(reply, register_category("news", "", "", _)).Times(1)
391 .WillOnce(Return(make_shared<sct::Category>("news", "", "", renderer)));
392
393 // We expect the art will fall back to the icon file
394 const string ICON_FILE = string(TEST_SCOPE_DIRECTORY).append("/euronews/icon.png");
395
396 // With two results
397 EXPECT_CALL(reply, push(Matcher<sc::CategorisedResult const&>(AllOf(
398 ResultProp("title", "US and Cuba differ on migration policy on first day of talks"),
399 ResultProp("art", ICON_FILE),
400 ResultProp("published", "Wed, 21 Jan 2015 21:38:01 GMT"),
401 ResultProp("summary", "Migration has proved a divisive issue on the first day of historic talks in Havana between senior Cuban and US officials - the first since both…"),
402 ResultProp("content", "Migration has proved a divisive issue on the first day of historic talks in Havana between senior Cuban and US officials - the first since both…")
403 )))).WillOnce(Return(true));
404 EXPECT_CALL(reply, push(Matcher<sc::CategorisedResult const&>(AllOf(
405 ResultProp("title", "PEGIDA leader quits amid 'Hitler' row"),
406 ResultProp("art", ICON_FILE),
407 ResultProp("published", "Wed, 21 Jan 2015 21:34:03 GMT"),
408 ResultProp("summary", "The leader of the anti-Islamisation PEGIDA party in Germany has quit amid a row over photo where he posed as Hitler and comments about immigrants on…"),
409 ResultProp("content", "The leader of the anti-Islamisation PEGIDA party in Germany has quit amid a row over photo where he posed as Hitler and comments about immigrants on…")
410 )))).WillOnce(Return(true));
411
412 sc::SearchReplyProxy reply_proxy(&reply, [](sc::SearchReply*) {}); // note: this is a std::shared_ptr with empty deleter
413 sc::SearchMetadata meta_data("en_EN", "phone");
414
415 // Create a query object
416 auto search_query = scope->search(query, meta_data);
417 ASSERT_NE(nullptr, search_query);
418
419 // Run the search
420 search_query->run(reply_proxy);
421
422 // Google Mock will make assertions when the mocks are destructed.
423}
424
425TEST_F(TestScopeEuronews, search) {
426 const sc::CategoryRenderer renderer;
427 NiceMock<sct::MockSearchReply> reply;
428
429 // Build a query with a non-empty search string
430 sc::CannedQuery query(SCOPE_NAME, "talks", "");
431
432 // Expect the current weather category
433 EXPECT_CALL(reply, register_category("news", "", "", _)).Times(1)
434 .WillOnce(Return(make_shared<sct::Category>("news", "", "", renderer)));
435
436 // We expect the art will fall back to the icon file
437 const string ICON_FILE = string(TEST_SCOPE_DIRECTORY).append("/euronews/icon.png");
438
439 // With one result
440 EXPECT_CALL(reply, push(Matcher<sc::CategorisedResult const&>(AllOf(
441 ResultProp("title", "US and Cuba differ on migration policy on first day of talks"),
442 ResultProp("art", ICON_FILE),
443 ResultProp("published", "Wed, 21 Jan 2015 21:38:01 GMT"),
444 ResultProp("summary", "Migration has proved a divisive issue on the first day of historic talks in Havana between senior Cuban and US officials - the first since both…"),
445 ResultProp("content", "Migration has proved a divisive issue on the first day of historic talks in Havana between senior Cuban and US officials - the first since both…")
446 )))).WillOnce(Return(true));
447
448 sc::SearchReplyProxy reply_proxy(&reply, [](sc::SearchReply*) {}); // note: this is a std::shared_ptr with empty deleter
449 sc::SearchMetadata meta_data("en_EN", "phone");
450
451 // Create a query object
452 auto search_query = scope->search(query, meta_data);
453 ASSERT_NE(nullptr, search_query);
454
455 // Run the search
456 search_query->run(reply_proxy);
457
458 // Google Mock will make assertions when the mocks are destructed.
459}
460
461class TestScopeElpais : public TestScope {
462protected:
463 void SetUp() override
464 {
465 TestScope::SetUp("elpais");
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to all changes: