Merge lp:~unity-team/libusermetrics/end-to-end into lp:~unity-team/libusermetrics/file-based-infographics
- end-to-end
- Merge into file-based-infographics
Status: | Merged |
---|---|
Merged at revision: | 150 |
Proposed branch: | lp:~unity-team/libusermetrics/end-to-end |
Merge into: | lp:~unity-team/libusermetrics/file-based-infographics |
Diff against target: |
5881 lines (+4025/-1090) 86 files modified
CMakeLists.txt (+7/-0) data/CMakeLists.txt (+70/-1) data/com.canonical.Infographics.conf (+15/-0) data/com.canonical.Infographics.service.in (+5/-0) data/com.canonical.Infographics.xml (+14/-0) data/com.canonical.UserMetrics.conf (+0/-15) data/default.json.in (+9/-0) data/usermetricsservice.conf.in (+10/-0) debian/changelog (+1/-1) debian/control (+3/-1) debian/libusermetricsinput1.symbols (+18/-18) debian/libusermetricsoutput1.symbols (+11/-0) debian/rules (+12/-2) debian/usermetricsservice.infographic.click-hook (+3/-0) debian/usermetricsservice.install (+2/-0) debian/usermetricsservice.postinst (+16/-0) debian/usermetricsservice.postrm (+26/-0) debian/usermetricsservice.preinst (+30/-0) debian/usermetricsservice.prerm (+7/-0) debian/usermetricsservice.usermetrics.click-hook (+3/-0) doc/Infographic Architecture.svg (+636/-0) po/en_GB.po (+5/-4) po/libusermetrics.pot (+1/-1) src/CMakeLists.txt (+1/-0) src/infographic/CMakeLists.txt (+2/-2) src/infographic/main.cpp (+9/-4) src/infographicservice/CMakeLists.txt (+58/-0) src/infographicservice/Service.cpp (+131/-0) src/infographicservice/Service.h (+74/-0) src/infographicservice/main.cpp (+46/-0) src/libusermetricscommon/CMakeLists.txt (+8/-1) src/libusermetricscommon/DBusPaths.h (+37/-0) src/libusermetricscommon/FileUtils.cpp (+52/-0) src/libusermetricscommon/FileUtils.h (+47/-0) src/libusermetricsinput/MetricImpl.cpp (+23/-6) src/libusermetricsinput/MetricImpl.h (+2/-0) src/libusermetricsinput/MetricManagerImpl.cpp (+19/-1) src/libusermetricsoutput/CMakeLists.txt (+3/-0) src/libusermetricsoutput/DirectoryWatcher.cpp (+114/-0) src/libusermetricsoutput/DirectoryWatcher.h (+69/-0) src/libusermetricsoutput/InfographicList.cpp (+32/-0) src/libusermetricsoutput/InfographicList.h (+106/-0) src/libusermetricsoutput/InfographicListImpl.cpp (+139/-0) src/libusermetricsoutput/InfographicListImpl.h (+79/-0) src/usermetricsservice/CMakeLists.txt (+62/-19) src/usermetricsservice/DBusUserData.cpp (+0/-186) src/usermetricsservice/Executor.cpp (+27/-0) src/usermetricsservice/Executor.h (+42/-0) src/usermetricsservice/Factory.cpp (+90/-0) src/usermetricsservice/Factory.h (+69/-0) src/usermetricsservice/Infographic.cpp (+27/-0) src/usermetricsservice/Infographic.h (+52/-0) src/usermetricsservice/InfographicImpl.cpp (+170/-0) src/usermetricsservice/InfographicImpl.h (+79/-0) src/usermetricsservice/QProcessExecutor.cpp (+75/-0) src/usermetricsservice/QProcessExecutor.h (+46/-0) src/usermetricsservice/ResultTransport.cpp (+27/-0) src/usermetricsservice/ResultTransport.h (+45/-0) src/usermetricsservice/ResultTransportImpl.cpp (+66/-0) src/usermetricsservice/ResultTransportImpl.h (+45/-0) src/usermetricsservice/Service.cpp (+27/-0) src/usermetricsservice/Service.h (+45/-0) src/usermetricsservice/ServiceImpl.cpp (+163/-0) src/usermetricsservice/ServiceImpl.h (+82/-0) src/usermetricsservice/SourceDirectory.cpp (+27/-0) src/usermetricsservice/SourceDirectory.h (+45/-0) src/usermetricsservice/SourceDirectoryImpl.cpp (+67/-0) src/usermetricsservice/SourceDirectoryImpl.h (+57/-0) src/usermetricsservice/aa-exec.cpp (+34/-0) src/usermetricsservice/main.cpp (+27/-2) tests/CMakeLists.txt (+5/-0) tests/data/infographics/test-aggregate.json (+13/-0) tests/data/infographics/test-iterate.json (+9/-0) tests/data/valgrind.suppression (+19/-0) tests/unit/libusermetricsinput/TestMetricImpl.cpp (+1/-1) tests/unit/libusermetricsinput/TestMetricManagerImpl.cpp (+15/-12) tests/unit/libusermetricsinput/TestUserMetricInputCAPI.cpp (+2/-2) tests/unit/libusermetricsoutput/CMakeLists.txt (+1/-0) tests/unit/libusermetricsoutput/TestInfographicListImpl.cpp (+122/-0) tests/unit/qml/UserMetricsTest/DBusQuery.cpp (+2/-2) tests/unit/qml/UserMetricsTest/TestPlugin.cpp (+3/-2) tests/unit/usermetricsservice/CMakeLists.txt (+25/-0) tests/unit/usermetricsservice/Mocks.h (+84/-0) tests/unit/usermetricsservice/TestInfographicImpl.cpp (+124/-0) tests/unit/usermetricsservice/TestServiceImpl.cpp (+149/-0) tests/unit/usermetricsservice/TestUserMetricsService.cpp (+0/-807) |
To merge this branch: | bzr merge lp:~unity-team/libusermetrics/end-to-end |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Michał Sawicz | api | Approve | |
PS Jenkins bot (community) | continuous-integration | Needs Fixing | |
Antti Kaijanmäki | Pending | ||
Review via email: mp+210435@code.launchpad.net |
Commit message
Checking what Jenkins thinks
Description of the change
Checking what Jenkins thinks
- 170. By Pete Woods
-
Don't know what these are for
- 171. By Pete Woods
-
Dead file
- 172. By Pete Woods
-
Suppress leaks in Qt
- 173. By Pete Woods
-
Merge Qt 5.2 branch
- 174. By Pete Woods
-
Fix up the symbols files
- 175. By Pete Woods
-
Infographic service writes files with timestamps that get aged off
- 176. By Pete Woods
-
This check breaks things when using atomic file writes
- 177. By Pete Woods
-
Disabling Valgrind until someone fixes the rules for Qt 5.2
Pete Woods (pete-woods) wrote : | # |
> Hey, this is looking good, I'll try and skim through this for a code review,
> but I've a few comments looking at the API:
>
> - there's no reason for the separate infographics property, just make
> InfographicsList a QAbstractListModel (any reason for using *ItemModel
> instead, btw?) with just a "source" role
>
> - as discussed on IRC, the filesUpdated() signal feels like a dirty API, I'd
> rather see timestamped file names and dataChanged on the "source" role when
> applicable; ideally both files would be available at the same time for a while
> (old files periodically garbage collected, basically?), in case we're still
> loading the old file while a new one got added
I have made these changes now. :)
>
> - the timeout logic feels unnecessary, we'll only be loading a single file
> (two at most during transitions); throttling should probably happen on the
> visualizer side, though?
>
I have found the QFileSystemWatcher API to be "noisy", and it sometimes emits duplicate events. Similar throttling occurs in response to the data changes for the visualisers, too, though.
> - should we be (are we?) running the visualizers whenever data changes, or
> only when greeter is shown? on one hand that would mean they're ready when
> greeter is shown, on the other they might never be shown at all (in case user
> never switches between images)
>
We're currently running them whenever data changes. There is only one-way communication to libusermetricso
> BTW, what's the plan for i18n? Are we ok with the SVGs only updating the
> language on next update, or should we maybe kick the visualisers on locale
> change?
At the moment, it's just the locale that the user was last logged in as. On login we do refresh all the SVGs, however.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:524
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Michał Sawicz (saviq) wrote : | # |
224 -libusermetrics (2.0.0-0ubuntu1) UNRELEASED; urgency=medium
225 +libusermetrics (1.2.0-0ubuntu1) UNRELEASED; urgency=medium
That looks wrong?
=====
1656 +static QRegularExpression CLICK_REGEX(
1657 + "^[a-z0-
1658 +
1815 +static QRegularExpression CLICK_REGEX(
1816 + "^[a-z0-
Seeing a regex like that makes me twinge already, but having it twice!
=====
2086 + return new InfographicList
Do we want that hardcoded? Isn't there somewhere we could request the /var/lib/ part from?
=====
2132 + * Given a user ID, this class watches the corresponding
2133 + *
You fell asleep there, did you?
=====
2139 + * @brief The current username selected.
2140 + */
2141 +Q_PROPERTY(
User Id, not username.
- 178. By Pete Woods
-
Respond to Saviq's review comments
Preview Diff
1 | === modified file 'CMakeLists.txt' |
2 | --- CMakeLists.txt 2014-01-03 12:54:25 +0000 |
3 | +++ CMakeLists.txt 2014-04-03 13:02:15 +0000 |
4 | @@ -16,12 +16,18 @@ |
5 | find_package(Qt5Core REQUIRED) |
6 | include_directories(${Qt5Core_INCLUDE_DIRS}) |
7 | |
8 | +find_package(Qt5DBus REQUIRED) |
9 | +include_directories(${Qt5DBus_INCLUDE_DIRS}) |
10 | + |
11 | find_package(Qt5Gui REQUIRED) |
12 | include_directories(${Qt5Gui_INCLUDE_DIRS}) |
13 | |
14 | find_package(Qt5XmlPatterns REQUIRED) |
15 | include_directories(${Qt5XmlPatterns_INCLUDE_DIRS}) |
16 | |
17 | +pkg_check_modules(APPARMOR REQUIRED libapparmor REQUIRED) |
18 | +include_directories(${APPARMOR_INCLUDE_DIRS}) |
19 | + |
20 | pkg_check_modules(GSETTINGS_QT REQUIRED gsettings-qt REQUIRED) |
21 | include_directories(${GSETTINGS_QT_INCLUDE_DIRS}) |
22 | |
23 | @@ -35,6 +41,7 @@ |
24 | set(CMAKE_INCLUDE_CURRENT_DIR ON) |
25 | |
26 | set(DATA_DIR "${CMAKE_CURRENT_SOURCE_DIR}/data") |
27 | +set(INFOGRAPHIC_SERVICE_XML "${DATA_DIR}/com.canonical.Infographics.xml") |
28 | |
29 | set(INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include") |
30 | set(INCLUDE_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/include") |
31 | |
32 | === modified file 'data/CMakeLists.txt' |
33 | --- data/CMakeLists.txt 2014-01-03 11:40:22 +0000 |
34 | +++ data/CMakeLists.txt 2014-04-03 13:02:15 +0000 |
35 | @@ -14,6 +14,22 @@ |
36 | ) |
37 | |
38 | ########################### |
39 | +# Default infographic |
40 | +########################### |
41 | + |
42 | +configure_file( |
43 | + "default.json.in" |
44 | + "${CMAKE_CURRENT_BINARY_DIR}/default.json" @ONLY |
45 | +) |
46 | + |
47 | +install( |
48 | + FILES |
49 | + "${CMAKE_CURRENT_BINARY_DIR}/default.json" |
50 | + DESTINATION |
51 | + "${CMAKE_INSTALL_DATADIR}/libusermetrics/infographics/" |
52 | +) |
53 | + |
54 | +########################### |
55 | # Policy |
56 | ########################### |
57 | |
58 | @@ -24,7 +40,60 @@ |
59 | |
60 | install( |
61 | FILES |
62 | - "com.canonical.UserMetrics.conf" |
63 | + "com.canonical.Infographics.conf" |
64 | DESTINATION ${DBUSCONFDIR} |
65 | ) |
66 | |
67 | +########################### |
68 | +# Dbus Interfaces |
69 | +########################### |
70 | + |
71 | +set( |
72 | + DBUSIFACEDIR |
73 | + "${CMAKE_INSTALL_DATADIR}/dbus-1/interfaces/" |
74 | +) |
75 | + |
76 | +install( |
77 | + FILES |
78 | + com.canonical.Infographics.xml |
79 | + DESTINATION ${DBUSIFACEDIR} |
80 | +) |
81 | + |
82 | +########################### |
83 | +# Dbus Services |
84 | +########################### |
85 | + |
86 | +set( |
87 | + DBUSSERVICEDIR |
88 | + "${CMAKE_INSTALL_DATADIR}/dbus-1/system-services/" |
89 | +) |
90 | + |
91 | +set(INFOGRAPHICS_SERVICE |
92 | + "${CMAKE_CURRENT_BINARY_DIR}/com.canonical.Infographics.service" |
93 | +) |
94 | + |
95 | +configure_file( |
96 | + "com.canonical.Infographics.service.in" |
97 | + ${INFOGRAPHICS_SERVICE} |
98 | + @ONLY |
99 | +) |
100 | + |
101 | +install( |
102 | + FILES |
103 | + ${INFOGRAPHICS_SERVICE} |
104 | + DESTINATION ${DBUSSERVICEDIR} |
105 | +) |
106 | + |
107 | +############################## |
108 | +# Usermetrics session service |
109 | +############################## |
110 | + |
111 | +configure_file( |
112 | + "usermetricsservice.conf.in" |
113 | + "${CMAKE_CURRENT_BINARY_DIR}/usermetricsservice.conf" @ONLY |
114 | +) |
115 | + |
116 | +install( |
117 | + FILES "${CMAKE_CURRENT_BINARY_DIR}/usermetricsservice.conf" |
118 | + DESTINATION "${CMAKE_INSTALL_DATADIR}/upstart/sessions" |
119 | +) |
120 | |
121 | === added file 'data/com.canonical.Infographics.conf' |
122 | --- data/com.canonical.Infographics.conf 1970-01-01 00:00:00 +0000 |
123 | +++ data/com.canonical.Infographics.conf 2014-04-03 13:02:15 +0000 |
124 | @@ -0,0 +1,15 @@ |
125 | +<!DOCTYPE busconfig PUBLIC |
126 | + "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" |
127 | + "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> |
128 | +<busconfig> |
129 | + |
130 | + <policy user="usermetrics"> |
131 | + <allow own="com.canonical.Infographics"/> |
132 | + </policy> |
133 | + |
134 | + <policy context="default"> |
135 | + <allow send_destination="com.canonical.Infographics"/> |
136 | + <allow receive_sender="com.canonical.Infographics"/> |
137 | + </policy> |
138 | + |
139 | +</busconfig> |
140 | |
141 | === added file 'data/com.canonical.Infographics.service.in' |
142 | --- data/com.canonical.Infographics.service.in 1970-01-01 00:00:00 +0000 |
143 | +++ data/com.canonical.Infographics.service.in 2014-04-03 13:02:15 +0000 |
144 | @@ -0,0 +1,5 @@ |
145 | +[D-BUS Service] |
146 | +Name=com.canonical.Infographics |
147 | +Exec=@CMAKE_INSTALL_FULL_LIBEXECDIR@/libusermetrics/infographicservice |
148 | +User=usermetrics |
149 | +StandardOutput=syslog |
150 | |
151 | === added file 'data/com.canonical.Infographics.xml' |
152 | --- data/com.canonical.Infographics.xml 1970-01-01 00:00:00 +0000 |
153 | +++ data/com.canonical.Infographics.xml 2014-04-03 13:02:15 +0000 |
154 | @@ -0,0 +1,14 @@ |
155 | +<?xml version="1.0" encoding="UTF-8"?> |
156 | +<node name="/"> |
157 | + <interface name="com.canonical.Infographics"> |
158 | + <method name="update"> |
159 | + <!-- in --> |
160 | + <arg type="s" name="visualizer" direction="in"/> |
161 | + <arg type="as" name="sources" direction="in"/> |
162 | + <arg type="s" name="file" direction="in"/> |
163 | + </method> |
164 | + |
165 | + <method name="clear"> |
166 | + </method> |
167 | + </interface> |
168 | +</node> |
169 | |
170 | === removed file 'data/com.canonical.UserMetrics.conf' |
171 | --- data/com.canonical.UserMetrics.conf 2013-07-01 17:13:45 +0000 |
172 | +++ data/com.canonical.UserMetrics.conf 1970-01-01 00:00:00 +0000 |
173 | @@ -1,15 +0,0 @@ |
174 | -<!DOCTYPE busconfig PUBLIC |
175 | - "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" |
176 | - "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> |
177 | -<busconfig> |
178 | - |
179 | - <policy user="usermetrics"> |
180 | - <allow own="com.canonical.UserMetrics"/> |
181 | - </policy> |
182 | - |
183 | - <policy context="default"> |
184 | - <allow send_destination="com.canonical.UserMetrics"/> |
185 | - <allow receive_sender="com.canonical.UserMetrics"/> |
186 | - </policy> |
187 | - |
188 | -</busconfig> |
189 | \ No newline at end of file |
190 | |
191 | === added file 'data/default.json.in' |
192 | --- data/default.json.in 1970-01-01 00:00:00 +0000 |
193 | +++ data/default.json.in 2014-04-03 13:02:15 +0000 |
194 | @@ -0,0 +1,9 @@ |
195 | +{ |
196 | + "exec": "@CMAKE_INSTALL_FULL_LIBEXECDIR@/libusermetrics/infographic", |
197 | + "type": "iterate", |
198 | + "input": { |
199 | + "*": [ |
200 | + ".*.libusermetrics.json" |
201 | + ] |
202 | + } |
203 | +} |
204 | |
205 | === added file 'data/usermetricsservice.conf.in' |
206 | --- data/usermetricsservice.conf.in 1970-01-01 00:00:00 +0000 |
207 | +++ data/usermetricsservice.conf.in 2014-04-03 13:02:15 +0000 |
208 | @@ -0,0 +1,10 @@ |
209 | +description "Service to connect infographic data sources to infographic visualizations" |
210 | + |
211 | +start on desktop-start |
212 | +stop on desktop-end |
213 | + |
214 | +respawn |
215 | +respawn limit 5 10 |
216 | + |
217 | +exec @CMAKE_INSTALL_FULL_LIBEXECDIR@/libusermetrics/usermetricsservice |
218 | + |
219 | |
220 | === modified file 'debian/changelog' |
221 | --- debian/changelog 2014-01-06 09:37:47 +0000 |
222 | +++ debian/changelog 2014-04-03 13:02:15 +0000 |
223 | @@ -1,4 +1,4 @@ |
224 | -libusermetrics (2.0.0-0ubuntu1) UNRELEASED; urgency=medium |
225 | +libusermetrics (1.2.0-0ubuntu1) UNRELEASED; urgency=medium |
226 | |
227 | * Remove the usermetrics database and store metrics in json files |
228 | inside the ~/.cache directory. |
229 | |
230 | === modified file 'debian/control' |
231 | --- debian/control 2014-01-06 10:08:27 +0000 |
232 | +++ debian/control 2014-04-03 13:02:15 +0000 |
233 | @@ -1,12 +1,14 @@ |
234 | Source: libusermetrics |
235 | Priority: optional |
236 | Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com> |
237 | -Build-Depends: cmake, |
238 | +Build-Depends: click-dev (>= 0.2.2), |
239 | + cmake, |
240 | dbus, |
241 | debhelper (>= 9), |
242 | doxygen, |
243 | gettext, |
244 | google-mock (>= 1.6.0+svn437), |
245 | + libapparmor-dev, |
246 | libgsettings-qt-dev, |
247 | libgtest-dev, |
248 | libqt5xmlpatterns5-dev, |
249 | |
250 | === modified file 'debian/libusermetricsinput1.symbols' |
251 | --- debian/libusermetricsinput1.symbols 2014-01-06 10:00:38 +0000 |
252 | +++ debian/libusermetricsinput1.symbols 2014-04-03 13:02:15 +0000 |
253 | @@ -17,25 +17,25 @@ |
254 | (c++)"UserMetricsInput::MetricParameters::maximum(double)@Base" 1.1.1 |
255 | (c++)"UserMetricsInput::MetricParameters::minimum(double)@Base" 1.1.1 |
256 | (c++)"UserMetricsInput::MetricParameters::MetricParameters(QString const&)@Base" 1.1.1 |
257 | - (c++)"UserMetricsInput::MetricParameters::MetricParameters(UserMetricsInput::MetricParameters const&)@Base" 2.0.0 |
258 | + (c++)"UserMetricsInput::MetricParameters::MetricParameters(UserMetricsInput::MetricParameters const&)@Base" 0replaceme |
259 | (c++)"UserMetricsInput::MetricParameters::MetricParameters(QString const&)@Base" 1.1.1 |
260 | - (c++)"UserMetricsInput::MetricParameters::MetricParameters(UserMetricsInput::MetricParameters const&)@Base" 2.0.0 |
261 | - (c++)"UserMetricsInput::MetricParameters::~MetricParameters()@Base" 1.1.1 |
262 | - (c++)"UserMetricsInput::MetricParameters::~MetricParameters()@Base" 1.1.1 |
263 | - (c++)"UserMetricsInput::MetricParameters::~MetricParameters()@Base" 1.1.1 |
264 | - (c++)"UserMetricsInput::MetricParameters::operator=(UserMetricsInput::MetricParameters const&)@Base" 2.0.0 |
265 | - (c++)"UserMetricsInput::Metric::Metric(QObject*)@Base" 1.0.1 |
266 | - (c++)"UserMetricsInput::Metric::Metric(QObject*)@Base" 1.0.1 |
267 | - (c++)"UserMetricsInput::Metric::~Metric()@Base" 1.0.1 |
268 | - (c++)"UserMetricsInput::Metric::~Metric()@Base" 1.0.1 |
269 | - (c++)"UserMetricsInput::Metric::~Metric()@Base" 1.0.1 |
270 | - (c++)"UserMetricsInput::MetricParameters::textDomain() const@Base" 2.0.0 |
271 | - (c++)"UserMetricsInput::MetricParameters::formatString() const@Base" 2.0.0 |
272 | - (c++)"UserMetricsInput::MetricParameters::emptyDataString() const@Base" 2.0.0 |
273 | - (c++)"UserMetricsInput::MetricParameters::id() const@Base" 2.0.0 |
274 | - (c++)"UserMetricsInput::MetricParameters::type() const@Base" 2.0.0 |
275 | - (c++)"UserMetricsInput::MetricParameters::options() const@Base" 2.0.0 |
276 | - (c++)"UserMetricsInput::MetricParameters::operator==(UserMetricsInput::MetricParameters const&) const@Base" 2.0.0 |
277 | + (c++)"UserMetricsInput::MetricParameters::MetricParameters(UserMetricsInput::MetricParameters const&)@Base" 0replaceme |
278 | + (c++)"UserMetricsInput::MetricParameters::~MetricParameters()@Base" 1.1.1 |
279 | + (c++)"UserMetricsInput::MetricParameters::~MetricParameters()@Base" 1.1.1 |
280 | + (c++)"UserMetricsInput::MetricParameters::~MetricParameters()@Base" 1.1.1 |
281 | + (c++)"UserMetricsInput::MetricParameters::operator=(UserMetricsInput::MetricParameters const&)@Base" 0replaceme |
282 | + (c++)"UserMetricsInput::Metric::Metric(QObject*)@Base" 1.0.1 |
283 | + (c++)"UserMetricsInput::Metric::Metric(QObject*)@Base" 1.0.1 |
284 | + (c++)"UserMetricsInput::Metric::~Metric()@Base" 1.0.1 |
285 | + (c++)"UserMetricsInput::Metric::~Metric()@Base" 1.0.1 |
286 | + (c++)"UserMetricsInput::Metric::~Metric()@Base" 1.0.1 |
287 | + (c++)"UserMetricsInput::MetricParameters::textDomain() const@Base" 0replaceme |
288 | + (c++)"UserMetricsInput::MetricParameters::formatString() const@Base" 0replaceme |
289 | + (c++)"UserMetricsInput::MetricParameters::emptyDataString() const@Base" 0replaceme |
290 | + (c++)"UserMetricsInput::MetricParameters::id() const@Base" 0replaceme |
291 | + (c++)"UserMetricsInput::MetricParameters::type() const@Base" 0replaceme |
292 | + (c++)"UserMetricsInput::MetricParameters::options() const@Base" 0replaceme |
293 | + (c++)"UserMetricsInput::MetricParameters::operator==(UserMetricsInput::MetricParameters const&) const@Base" 0replaceme |
294 | (c++)"typeinfo for UserMetricsInput::MetricUpdate@Base" 1.0.1 |
295 | (c++)"typeinfo for UserMetricsInput::MetricManager@Base" 1.0.1 |
296 | (c++)"typeinfo for UserMetricsInput::MetricParameters@Base" 1.1.1 |
297 | |
298 | === modified file 'debian/libusermetricsoutput1.symbols' |
299 | --- debian/libusermetricsoutput1.symbols 2013-06-20 15:59:31 +0000 |
300 | +++ debian/libusermetricsoutput1.symbols 2014-04-03 13:02:15 +0000 |
301 | @@ -34,11 +34,22 @@ |
302 | (c++)"UserMetricsOutput::UserMetrics::~UserMetrics()@Base" 1.0.1 |
303 | (c++)"UserMetricsOutput::UserMetrics::~UserMetrics()@Base" 1.0.1 |
304 | (c++)"UserMetricsOutput::UserMetrics::~UserMetrics()@Base" 1.0.1 |
305 | + (c++)"UserMetricsOutput::InfographicList::uidChanged(unsigned int)@Base" 0replaceme |
306 | + (c++)"UserMetricsOutput::InfographicList::getInstance()@Base" 0replaceme |
307 | + (c++)"UserMetricsOutput::InfographicList::qt_metacall(QMetaObject::Call, int, void**)@Base" 0replaceme |
308 | + (c++)"UserMetricsOutput::InfographicList::qt_metacast(char const*)@Base" 0replaceme |
309 | + (c++)"UserMetricsOutput::InfographicList::staticMetaObject@Base" 0replaceme |
310 | + (c++)"UserMetricsOutput::InfographicList::InfographicList(QObject*)@Base" 0replaceme |
311 | + (c++)"UserMetricsOutput::InfographicList::~InfographicList()@Base" 0replaceme |
312 | + (c++)"UserMetricsOutput::InfographicList::metaObject() const@Base" 0replaceme |
313 | (c++)"UserMetricsOutput::ColorTheme::metaObject() const@Base" 1.0.1 |
314 | (c++)"UserMetricsOutput::UserMetrics::metaObject() const@Base" 1.0.1 |
315 | (c++)"typeinfo for UserMetricsOutput::ColorTheme@Base" 1.0.1 |
316 | (c++)"typeinfo for UserMetricsOutput::UserMetrics@Base" 1.0.1 |
317 | (c++)"typeinfo name for UserMetricsOutput::ColorTheme@Base" 1.0.1 |
318 | (c++)"typeinfo name for UserMetricsOutput::UserMetrics@Base" 1.0.1 |
319 | + (c++)"typeinfo for UserMetricsOutput::InfographicList@Base" 0replaceme |
320 | + (c++)"typeinfo name for UserMetricsOutput::InfographicList@Base" 0replaceme |
321 | (c++)"vtable for UserMetricsOutput::ColorTheme@Base" 1.0.1 |
322 | + (c++)"vtable for UserMetricsOutput::InfographicList@Base" 0replaceme |
323 | (c++)"vtable for UserMetricsOutput::UserMetrics@Base" 1.0.1 |
324 | |
325 | === modified file 'debian/rules' |
326 | --- debian/rules 2013-07-04 10:30:17 +0000 |
327 | +++ debian/rules 2014-04-03 13:02:15 +0000 |
328 | @@ -3,11 +3,21 @@ |
329 | |
330 | export DPKG_GENSYMBOLS_CHECK_LEVEL=4 |
331 | |
332 | +ifeq ($(DEB_HOST_ARCH),armhf) |
333 | + ENABLE_MEMCHECK_OPTION = OFF |
334 | +else |
335 | + ENABLE_MEMCHECK_OPTION = OFF |
336 | +endif |
337 | + |
338 | %: |
339 | - dh $@ --parallel --fail-missing |
340 | + dh $@ --parallel --fail-missing --with click |
341 | |
342 | override_dh_auto_configure: |
343 | - dh_auto_configure -- -DBUILD_DOXYGEN=YES -DENABLE_MEMCHECK_OPTION=YES |
344 | + dh_auto_configure -- -DBUILD_DOXYGEN=YES -DENABLE_MEMCHECK_OPTION=${ENABLE_MEMCHECK_OPTION} |
345 | |
346 | override_dh_makeshlibs: |
347 | dh_makeshlibs -V |
348 | + |
349 | +override_dh_click: |
350 | + dh_click --name infographic |
351 | + dh_click --name usermetrics |
352 | |
353 | === added file 'debian/usermetricsservice.infographic.click-hook' |
354 | --- debian/usermetricsservice.infographic.click-hook 1970-01-01 00:00:00 +0000 |
355 | +++ debian/usermetricsservice.infographic.click-hook 2014-04-03 13:02:15 +0000 |
356 | @@ -0,0 +1,3 @@ |
357 | +Pattern: ${home}/.cache/usermetrics/infographics/${id}.json |
358 | +User-Level: yes |
359 | +Hook-Name: infographic |
360 | |
361 | === modified file 'debian/usermetricsservice.install' |
362 | --- debian/usermetricsservice.install 2014-01-03 16:58:40 +0000 |
363 | +++ debian/usermetricsservice.install 2014-04-03 13:02:15 +0000 |
364 | @@ -1,5 +1,7 @@ |
365 | etc |
366 | usr/lib/*/libusermetrics |
367 | +usr/share/dbus-1 |
368 | usr/share/glib-2.0 |
369 | usr/share/libusermetrics |
370 | usr/share/locale |
371 | +usr/share/upstart |
372 | |
373 | === added file 'debian/usermetricsservice.postinst' |
374 | --- debian/usermetricsservice.postinst 1970-01-01 00:00:00 +0000 |
375 | +++ debian/usermetricsservice.postinst 2014-04-03 13:02:15 +0000 |
376 | @@ -0,0 +1,16 @@ |
377 | +#!/bin/sh |
378 | + |
379 | +set -e |
380 | + |
381 | +. /usr/share/debconf/confmodule |
382 | + |
383 | +dbus-send --system --print-reply \ |
384 | + --dest=org.freedesktop.DBus \ |
385 | + /org/freedesktop/DBus \ |
386 | + org.freedesktop.DBus.StartServiceByName \ |
387 | + string:"com.canonical.Infographics" uint32:0 \ |
388 | + || true |
389 | + |
390 | +#DEBHELPER# |
391 | + |
392 | +exit 0 |
393 | |
394 | === added file 'debian/usermetricsservice.postrm' |
395 | --- debian/usermetricsservice.postrm 1970-01-01 00:00:00 +0000 |
396 | +++ debian/usermetricsservice.postrm 2014-04-03 13:02:15 +0000 |
397 | @@ -0,0 +1,26 @@ |
398 | +#!/bin/sh |
399 | +set -e |
400 | + |
401 | +if [ "$1" = "purge" ] ; then |
402 | + if getent passwd usermetrics >/dev/null; then |
403 | + if [ -x /usr/sbin/deluser ]; then |
404 | + deluser --system usermetrics |
405 | + fi |
406 | + fi |
407 | + |
408 | + if getent group usermetrics >/dev/null; then |
409 | + if [ -x /usr/sbin/delgroup ]; then |
410 | + delgroup --system usermetrics |
411 | + fi |
412 | + fi |
413 | + |
414 | + # we cannot use the --remove-home option when we delete the user above |
415 | + # because it will refuse to remove things in /var, so clean it up this |
416 | + # way |
417 | + if [ -d /var/lib/usermetrics ]; then |
418 | + rm -r /var/lib/usermetrics |
419 | + fi |
420 | + |
421 | +fi |
422 | +#DEBHELPER# |
423 | +exit 0 |
424 | |
425 | === added file 'debian/usermetricsservice.preinst' |
426 | --- debian/usermetricsservice.preinst 1970-01-01 00:00:00 +0000 |
427 | +++ debian/usermetricsservice.preinst 2014-04-03 13:02:15 +0000 |
428 | @@ -0,0 +1,30 @@ |
429 | +#!/bin/sh |
430 | + |
431 | +set -e |
432 | + |
433 | +. /usr/share/debconf/confmodule |
434 | + |
435 | +THIS_PACKAGE=usermetricsservice |
436 | + |
437 | +# creating usermetrics group if he isn't already there |
438 | +if ! getent group usermetrics >/dev/null; then |
439 | + addgroup --system usermetrics |
440 | +fi |
441 | + |
442 | +# creating usermetrics user if he isn't already there |
443 | +if ! getent passwd usermetrics >/dev/null; then |
444 | + adduser --system --ingroup usermetrics --home /var/lib/usermetrics usermetrics |
445 | + usermod -c "User Metrics" usermetrics |
446 | + usermod -d "/var/lib/usermetrics" usermetrics |
447 | + usermod -g "usermetrics" usermetrics |
448 | + usermod -s "/bin/false" usermetrics |
449 | +fi |
450 | + |
451 | +if [ -d /var/lib/usermetrics ]; then |
452 | + chown -R usermetrics:usermetrics /var/lib/usermetrics |
453 | + chmod 0755 /var/lib/usermetrics |
454 | +fi |
455 | + |
456 | +#DEBHELPER# |
457 | + |
458 | +exit 0 |
459 | |
460 | === added file 'debian/usermetricsservice.prerm' |
461 | --- debian/usermetricsservice.prerm 1970-01-01 00:00:00 +0000 |
462 | +++ debian/usermetricsservice.prerm 2014-04-03 13:02:15 +0000 |
463 | @@ -0,0 +1,7 @@ |
464 | +#!/bin/sh |
465 | + |
466 | +set -e |
467 | + |
468 | +pkill -U usermetrics 2>/dev/null || true |
469 | + |
470 | +#DEBHELPER# |
471 | \ No newline at end of file |
472 | |
473 | === added file 'debian/usermetricsservice.usermetrics.click-hook' |
474 | --- debian/usermetricsservice.usermetrics.click-hook 1970-01-01 00:00:00 +0000 |
475 | +++ debian/usermetricsservice.usermetrics.click-hook 2014-04-03 13:02:15 +0000 |
476 | @@ -0,0 +1,3 @@ |
477 | +Pattern: ${home}/.cache/usermetrics/sources/${id}.json |
478 | +User-Level: yes |
479 | +Hook-Name: usermetrics |
480 | |
481 | === added file 'doc/Infographic Architecture.svg' |
482 | --- doc/Infographic Architecture.svg 1970-01-01 00:00:00 +0000 |
483 | +++ doc/Infographic Architecture.svg 2014-04-03 13:02:15 +0000 |
484 | @@ -0,0 +1,636 @@ |
485 | +<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
486 | +<!-- Created with Inkscape (http://www.inkscape.org/) --> |
487 | + |
488 | +<svg |
489 | + xmlns:dc="http://purl.org/dc/elements/1.1/" |
490 | + xmlns:cc="http://creativecommons.org/ns#" |
491 | + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |
492 | + xmlns:svg="http://www.w3.org/2000/svg" |
493 | + xmlns="http://www.w3.org/2000/svg" |
494 | + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" |
495 | + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" |
496 | + width="671.98975" |
497 | + height="413.13217" |
498 | + id="svg2" |
499 | + version="1.1" |
500 | + inkscape:version="0.48.4 r9939" |
501 | + sodipodi:docname="infographics version 2.svg"> |
502 | + <defs |
503 | + id="defs4"> |
504 | + <inkscape:path-effect |
505 | + effect="spiro" |
506 | + id="path-effect4676" |
507 | + is_visible="true" /> |
508 | + <marker |
509 | + inkscape:stockid="Arrow1Mend" |
510 | + orient="auto" |
511 | + refY="0" |
512 | + refX="0" |
513 | + id="Arrow1Mend" |
514 | + style="overflow:visible"> |
515 | + <path |
516 | + id="path3951" |
517 | + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" |
518 | + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt" |
519 | + transform="matrix(-0.4,0,0,-0.4,-4,0)" |
520 | + inkscape:connector-curvature="0" /> |
521 | + </marker> |
522 | + <marker |
523 | + inkscape:stockid="Arrow1Mend" |
524 | + orient="auto" |
525 | + refY="0" |
526 | + refX="0" |
527 | + id="Arrow1Mend-3" |
528 | + style="overflow:visible"> |
529 | + <path |
530 | + inkscape:connector-curvature="0" |
531 | + id="path3951-3" |
532 | + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" |
533 | + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt" |
534 | + transform="matrix(-0.4,0,0,-0.4,-4,0)" /> |
535 | + </marker> |
536 | + <marker |
537 | + inkscape:stockid="Arrow1Mend" |
538 | + orient="auto" |
539 | + refY="0" |
540 | + refX="0" |
541 | + id="Arrow1Mend-3-5" |
542 | + style="overflow:visible"> |
543 | + <path |
544 | + inkscape:connector-curvature="0" |
545 | + id="path3951-3-8" |
546 | + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" |
547 | + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt" |
548 | + transform="matrix(-0.4,0,0,-0.4,-4,0)" /> |
549 | + </marker> |
550 | + <inkscape:path-effect |
551 | + effect="spiro" |
552 | + id="path-effect4676-5" |
553 | + is_visible="true" /> |
554 | + <marker |
555 | + inkscape:stockid="Arrow1Mend" |
556 | + orient="auto" |
557 | + refY="0" |
558 | + refX="0" |
559 | + id="Arrow1Mend-3-7" |
560 | + style="overflow:visible"> |
561 | + <path |
562 | + inkscape:connector-curvature="0" |
563 | + id="path3951-3-2" |
564 | + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" |
565 | + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt" |
566 | + transform="matrix(-0.4,0,0,-0.4,-4,0)" /> |
567 | + </marker> |
568 | + <marker |
569 | + inkscape:stockid="Arrow1Mend" |
570 | + orient="auto" |
571 | + refY="0" |
572 | + refX="0" |
573 | + id="Arrow1Mend-3-1" |
574 | + style="overflow:visible"> |
575 | + <path |
576 | + inkscape:connector-curvature="0" |
577 | + id="path3951-3-5" |
578 | + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" |
579 | + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt" |
580 | + transform="matrix(-0.4,0,0,-0.4,-4,0)" /> |
581 | + </marker> |
582 | + <marker |
583 | + inkscape:stockid="Arrow1Mend" |
584 | + orient="auto" |
585 | + refY="0" |
586 | + refX="0" |
587 | + id="Arrow1Mend-3-3" |
588 | + style="overflow:visible"> |
589 | + <path |
590 | + inkscape:connector-curvature="0" |
591 | + id="path3951-3-4" |
592 | + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" |
593 | + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt" |
594 | + transform="matrix(-0.4,0,0,-0.4,-4,0)" /> |
595 | + </marker> |
596 | + <marker |
597 | + inkscape:stockid="Arrow1Mend" |
598 | + orient="auto" |
599 | + refY="0" |
600 | + refX="0" |
601 | + id="Arrow1Mend-3-2" |
602 | + style="overflow:visible"> |
603 | + <path |
604 | + inkscape:connector-curvature="0" |
605 | + id="path3951-3-80" |
606 | + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" |
607 | + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt" |
608 | + transform="matrix(-0.4,0,0,-0.4,-4,0)" /> |
609 | + </marker> |
610 | + <marker |
611 | + inkscape:stockid="Arrow1Mend" |
612 | + orient="auto" |
613 | + refY="0" |
614 | + refX="0" |
615 | + id="Arrow1Mend-3-9" |
616 | + style="overflow:visible"> |
617 | + <path |
618 | + inkscape:connector-curvature="0" |
619 | + id="path3951-3-1" |
620 | + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" |
621 | + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt" |
622 | + transform="matrix(-0.4,0,0,-0.4,-4,0)" /> |
623 | + </marker> |
624 | + <marker |
625 | + inkscape:stockid="Arrow1Mend" |
626 | + orient="auto" |
627 | + refY="0" |
628 | + refX="0" |
629 | + id="Arrow1Mend-3-19" |
630 | + style="overflow:visible"> |
631 | + <path |
632 | + inkscape:connector-curvature="0" |
633 | + id="path3951-3-3" |
634 | + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" |
635 | + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt" |
636 | + transform="matrix(-0.4,0,0,-0.4,-4,0)" /> |
637 | + </marker> |
638 | + <marker |
639 | + inkscape:stockid="Arrow1Mend" |
640 | + orient="auto" |
641 | + refY="0" |
642 | + refX="0" |
643 | + id="Arrow1Mend-3-24" |
644 | + style="overflow:visible"> |
645 | + <path |
646 | + inkscape:connector-curvature="0" |
647 | + id="path3951-3-7" |
648 | + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" |
649 | + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt" |
650 | + transform="matrix(-0.4,0,0,-0.4,-4,0)" /> |
651 | + </marker> |
652 | + <inkscape:path-effect |
653 | + effect="spiro" |
654 | + id="path-effect4676-6" |
655 | + is_visible="true" /> |
656 | + </defs> |
657 | + <sodipodi:namedview |
658 | + id="base" |
659 | + pagecolor="#ffffff" |
660 | + bordercolor="#666666" |
661 | + borderopacity="1.0" |
662 | + inkscape:pageopacity="0.0" |
663 | + inkscape:pageshadow="2" |
664 | + inkscape:zoom="1.7277049" |
665 | + inkscape:cx="335.99487" |
666 | + inkscape:cy="206.56609" |
667 | + inkscape:document-units="px" |
668 | + inkscape:current-layer="layer1" |
669 | + showgrid="false" |
670 | + showguides="false" |
671 | + inkscape:window-width="1680" |
672 | + inkscape:window-height="1026" |
673 | + inkscape:window-x="0" |
674 | + inkscape:window-y="24" |
675 | + inkscape:window-maximized="1" |
676 | + fit-margin-top="20" |
677 | + fit-margin-left="20" |
678 | + fit-margin-right="20" |
679 | + fit-margin-bottom="20" /> |
680 | + <metadata |
681 | + id="metadata7"> |
682 | + <rdf:RDF> |
683 | + <cc:Work |
684 | + rdf:about=""> |
685 | + <dc:format>image/svg+xml</dc:format> |
686 | + <dc:type |
687 | + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> |
688 | + <dc:title /> |
689 | + </cc:Work> |
690 | + </rdf:RDF> |
691 | + </metadata> |
692 | + <g |
693 | + inkscape:label="Layer 1" |
694 | + inkscape:groupmode="layer" |
695 | + id="layer1" |
696 | + transform="translate(9.1737344,-608.13043)"> |
697 | + <g |
698 | + id="g3761" |
699 | + transform="translate(9.0102463,20.5802)"> |
700 | + <rect |
701 | + transform="translate(0,572.36218)" |
702 | + y="170.37543" |
703 | + x="244.09557" |
704 | + height="78.088745" |
705 | + width="133.78838" |
706 | + id="rect2985" |
707 | + style="color:#000000;fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> |
708 | + <text |
709 | + sodipodi:linespacing="100%" |
710 | + id="text3755" |
711 | + y="778.51001" |
712 | + x="310.46051" |
713 | + style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:100%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Ubuntu;-inkscape-font-specification:Ubuntu" |
714 | + xml:space="preserve"><tspan |
715 | + y="778.51001" |
716 | + x="310.46051" |
717 | + id="tspan3757" |
718 | + sodipodi:role="line">Infographic</tspan><tspan |
719 | + id="tspan3759" |
720 | + y="794.51001" |
721 | + x="310.46051" |
722 | + sodipodi:role="line">Helper</tspan></text> |
723 | + </g> |
724 | + <g |
725 | + id="g3803" |
726 | + transform="translate(-8.12897,0)"> |
727 | + <rect |
728 | + style="color:#000000;fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
729 | + id="rect3767" |
730 | + width="159.58728" |
731 | + height="87.497849" |
732 | + x="430.33533" |
733 | + y="56.268272" |
734 | + transform="translate(0,572.36218)" /> |
735 | + <text |
736 | + xml:space="preserve" |
737 | + style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Ubuntu;-inkscape-font-specification:Ubuntu" |
738 | + x="436.38864" |
739 | + y="677.60724" |
740 | + id="text3769" |
741 | + sodipodi:linespacing="100%"><tspan |
742 | + sodipodi:role="line" |
743 | + id="tspan3771" |
744 | + x="436.38864" |
745 | + y="677.60724" |
746 | + style="font-size:14px" |
747 | + dy="-4.9527082">Infographic Source</tspan><tspan |
748 | + sodipodi:role="line" |
749 | + x="436.38864" |
750 | + y="691.60724" |
751 | + id="tspan3773" |
752 | + style="font-size:14px"><tspan |
753 | + style="font-size:14px;font-weight:bold" |
754 | + id="tspan3777" |
755 | + dy="-0.55030096">type:</tspan> foo</tspan><tspan |
756 | + sodipodi:role="line" |
757 | + x="436.38864" |
758 | + y="705.60724" |
759 | + id="tspan3775" |
760 | + dx="0 0 0 0 0 0 0 0 0 0 -1.1006019" |
761 | + style="font-size:14px"><tspan |
762 | + style="font-size:14px;font-weight:bold" |
763 | + id="tspan3779">file:</tspan> infographic.foo</tspan></text> |
764 | + <rect |
765 | + style="color:#000000;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
766 | + id="rect3767-6" |
767 | + width="159.03699" |
768 | + height="26.414476" |
769 | + x="430.33533" |
770 | + y="628.63043" /> |
771 | + <text |
772 | + xml:space="preserve" |
773 | + style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Ubuntu;-inkscape-font-specification:Ubuntu" |
774 | + x="442.82819" |
775 | + y="647.92566" |
776 | + id="text3799" |
777 | + sodipodi:linespacing="100%"><tspan |
778 | + sodipodi:role="line" |
779 | + id="tspan3801" |
780 | + x="442.82819" |
781 | + y="647.92566">Foo Click Manifest</tspan></text> |
782 | + </g> |
783 | + <g |
784 | + id="g3918" |
785 | + transform="translate(-360,-2.1289061e-6)"> |
786 | + <rect |
787 | + y="628.63043" |
788 | + x="418.20636" |
789 | + height="87.497849" |
790 | + width="159.58728" |
791 | + id="rect3767-7" |
792 | + style="color:#000000;fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> |
793 | + <text |
794 | + sodipodi:linespacing="100%" |
795 | + id="text3769-5" |
796 | + y="677.60724" |
797 | + x="424.25967" |
798 | + style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Ubuntu;-inkscape-font-specification:Ubuntu" |
799 | + xml:space="preserve"><tspan |
800 | + dy="-4.9527082" |
801 | + style="font-size:14px" |
802 | + y="677.60724" |
803 | + x="424.25967" |
804 | + id="tspan3771-4" |
805 | + sodipodi:role="line">Infographic Sink</tspan><tspan |
806 | + style="font-size:14px" |
807 | + id="tspan3773-2" |
808 | + y="691.60724" |
809 | + x="424.25967" |
810 | + sodipodi:role="line"><tspan |
811 | + dy="-0.55030096" |
812 | + id="tspan3777-3" |
813 | + style="font-size:14px;font-weight:bold">type:</tspan> foo</tspan><tspan |
814 | + style="font-size:14px" |
815 | + dx="0 0 0 0 0 0 0 0 0 0 -1.1006019" |
816 | + id="tspan3775-4" |
817 | + y="705.60724" |
818 | + x="424.25967" |
819 | + sodipodi:role="line"><tspan |
820 | + id="tspan3779-2" |
821 | + style="font-size:14px;font-weight:bold">file:</tspan> infographic.svg</tspan></text> |
822 | + <rect |
823 | + y="628.63043" |
824 | + x="418.20636" |
825 | + height="26.414476" |
826 | + width="159.03699" |
827 | + id="rect3767-6-7" |
828 | + style="color:#000000;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> |
829 | + <text |
830 | + sodipodi:linespacing="100%" |
831 | + id="text3799-8" |
832 | + y="647.92566" |
833 | + x="431.91797" |
834 | + style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Ubuntu;-inkscape-font-specification:Ubuntu" |
835 | + xml:space="preserve"><tspan |
836 | + y="647.92566" |
837 | + x="431.91797" |
838 | + id="tspan3801-6" |
839 | + sodipodi:role="line">Bar Click Manifest</tspan></text> |
840 | + </g> |
841 | + <text |
842 | + sodipodi:linespacing="100%" |
843 | + id="text3930" |
844 | + y="701.8205" |
845 | + x="319.61853" |
846 | + style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:100%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Ubuntu;-inkscape-font-specification:Ubuntu" |
847 | + xml:space="preserve"><tspan |
848 | + y="701.8205" |
849 | + x="319.61853" |
850 | + id="tspan3932" |
851 | + sodipodi:role="line">Install</tspan><tspan |
852 | + id="tspan3934" |
853 | + y="717.8205" |
854 | + x="319.61853" |
855 | + sodipodi:role="line">Hooks</tspan></text> |
856 | + <path |
857 | + inkscape:connector-curvature="0" |
858 | + id="path3936" |
859 | + d="m 226.17369,685.31145 c 45.12468,-1.1006 52.27859,36.31986 52.82889,67.13671" |
860 | + style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)" /> |
861 | + <path |
862 | + inkscape:connector-curvature="0" |
863 | + id="path3936-1" |
864 | + d="m 414.31778,685.49855 c -45.12468,-1.10061 -52.27859,36.31985 -52.82889,67.13671" |
865 | + style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend)" /> |
866 | + <g |
867 | + id="g4893"> |
868 | + <rect |
869 | + style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
870 | + id="rect4425" |
871 | + width="95.752365" |
872 | + height="95.752365" |
873 | + x="441.74377" |
874 | + y="751.89789" /> |
875 | + <text |
876 | + xml:space="preserve" |
877 | + style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:100%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Ubuntu;-inkscape-font-specification:Ubuntu" |
878 | + x="489.69073" |
879 | + y="796.50208" |
880 | + id="text4427" |
881 | + sodipodi:linespacing="100%"><tspan |
882 | + sodipodi:role="line" |
883 | + id="tspan4429" |
884 | + x="489.69073" |
885 | + y="796.50208">foo</tspan><tspan |
886 | + sodipodi:role="line" |
887 | + x="489.69073" |
888 | + y="812.50208" |
889 | + id="tspan4431">app</tspan></text> |
890 | + </g> |
891 | + <g |
892 | + id="g4469" |
893 | + transform="translate(-13.207223,24.763543)"> |
894 | + <rect |
895 | + y="887.29889" |
896 | + x="403.61313" |
897 | + height="35.715553" |
898 | + width="192.67056" |
899 | + id="rect2985-1" |
900 | + style="color:#000000;fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> |
901 | + <text |
902 | + sodipodi:linespacing="100%" |
903 | + id="text3755-5" |
904 | + y="908.72668" |
905 | + x="500.00146" |
906 | + style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:100%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Ubuntu;-inkscape-font-specification:Ubuntu" |
907 | + xml:space="preserve"><tspan |
908 | + id="tspan3759-8" |
909 | + y="908.72668" |
910 | + x="500.00146" |
911 | + sodipodi:role="line">~/.cache/$(appid)/infographic.foo</tspan></text> |
912 | + </g> |
913 | + <path |
914 | + style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend-3)" |
915 | + d="M 383.55976,356.18229 C 353.84351,354.53139 348.8908,331.96904 347.7902,280.79106" |
916 | + id="path4474" |
917 | + inkscape:connector-curvature="0" |
918 | + transform="translate(0,572.36218)" |
919 | + sodipodi:nodetypes="cc" /> |
920 | + <text |
921 | + xml:space="preserve" |
922 | + style="font-size:14px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Ubuntu;-inkscape-font-specification:Ubuntu Italic" |
923 | + x="361.54773" |
924 | + y="876.81616" |
925 | + id="text4660" |
926 | + sodipodi:linespacing="100%"><tspan |
927 | + sodipodi:role="line" |
928 | + id="tspan4662" |
929 | + x="361.54773" |
930 | + y="876.81616">File</tspan><tspan |
931 | + sodipodi:role="line" |
932 | + x="361.54773" |
933 | + y="890.81616" |
934 | + id="tspan4664">Watch</tspan></text> |
935 | + <text |
936 | + xml:space="preserve" |
937 | + style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:112.00000047999999708%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Ubuntu;-inkscape-font-specification:Ubuntu;opacity:0.75" |
938 | + x="571.7627" |
939 | + y="755.19965" |
940 | + id="text4666" |
941 | + sodipodi:linespacing="112%"><tspan |
942 | + sodipodi:role="line" |
943 | + id="tspan4668" |
944 | + x="571.7627" |
945 | + y="755.19965">Foo</tspan><tspan |
946 | + sodipodi:role="line" |
947 | + x="571.7627" |
948 | + y="768.63965" |
949 | + id="tspan4670">AppArmor</tspan><tspan |
950 | + sodipodi:role="line" |
951 | + x="571.7627" |
952 | + y="782.07965" |
953 | + id="tspan4672">Confinement</tspan></text> |
954 | + <path |
955 | + style="opacity:0.75;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend-3)" |
956 | + d="m 567.36028,192.74291 c -2.53774,-0.0622 -5.08926,0.61223 -7.26478,1.92031 -0.81305,0.48887 -1.57239,1.06245 -2.381,1.55863 -0.8086,0.49619 -1.68153,0.91914 -2.61893,1.06514 -1.39269,0.2169 -2.80076,-0.19097 -4.13805,-0.63627 -1.33729,-0.44531 -2.69883,-0.93906 -4.10774,-0.89876 -1.25072,0.0358 -2.44503,0.49048 -3.65682,0.80213 -0.33784,0.0869 -0.67847,0.16288 -1.0212,0.22784" |
957 | + id="path4674" |
958 | + inkscape:path-effect="#path-effect4676" |
959 | + inkscape:original-d="m 567.36028,192.74291 c -2.05099,4.0056 -2.57986,1.777 -7.26478,1.92031 -10.78275,0 -8.1675,12.44489 -4.99993,2.62377 3.3427,-11.96353 -5.33958,-3.07508 -8.24579,-1.53503 -2.9062,1.54005 -3.37007,1.24208 -3.65682,0.80213 -0.28674,-0.43995 -0.39635,-1.02187 -1.0212,0.22784" |
960 | + inkscape:connector-curvature="0" |
961 | + transform="translate(0,572.36218)" |
962 | + sodipodi:nodetypes="ccczsc" /> |
963 | + <g |
964 | + transform="translate(-341.88525,60.753484)" |
965 | + id="g4893-5"> |
966 | + <rect |
967 | + style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
968 | + id="rect4425-0" |
969 | + width="95.752365" |
970 | + height="95.752365" |
971 | + x="441.74377" |
972 | + y="751.89789" /> |
973 | + <text |
974 | + xml:space="preserve" |
975 | + style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:100%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Ubuntu;-inkscape-font-specification:Ubuntu" |
976 | + x="489.69073" |
977 | + y="796.50208" |
978 | + id="text4427-5" |
979 | + sodipodi:linespacing="100%"><tspan |
980 | + sodipodi:role="line" |
981 | + id="tspan4429-8" |
982 | + x="489.69073" |
983 | + y="796.50208">bar</tspan><tspan |
984 | + sodipodi:role="line" |
985 | + x="489.69073" |
986 | + y="812.50208" |
987 | + id="tspan4929">visual</tspan></text> |
988 | + </g> |
989 | + <text |
990 | + xml:space="preserve" |
991 | + style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:112.00000047999999708%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Ubuntu;-inkscape-font-specification:Ubuntu;opacity:0.75" |
992 | + x="10.730266" |
993 | + y="836.82312" |
994 | + id="text4666-3" |
995 | + sodipodi:linespacing="112%"><tspan |
996 | + sodipodi:role="line" |
997 | + id="tspan4668-4" |
998 | + x="10.730266" |
999 | + y="836.82312">Bar</tspan><tspan |
1000 | + sodipodi:role="line" |
1001 | + x="10.730266" |
1002 | + y="850.26312" |
1003 | + id="tspan4670-0">AppArmor</tspan><tspan |
1004 | + sodipodi:role="line" |
1005 | + x="10.730266" |
1006 | + y="863.70312" |
1007 | + id="tspan4672-9">Confinement</tspan></text> |
1008 | + <path |
1009 | + style="color:#000000;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#Arrow1Mend-3);visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
1010 | + d="m 118.51852,723.61908 c 0,0 0,-0.55125 0,78.82859" |
1011 | + id="path4987" |
1012 | + inkscape:connector-curvature="0" /> |
1013 | + <path |
1014 | + style="color:#000000;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#Arrow1Mend-3);visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
1015 | + d="m 490.06029,150.90439 c 0,22.60121 0,22.60121 0,22.60121" |
1016 | + id="path4989" |
1017 | + inkscape:connector-curvature="0" |
1018 | + transform="translate(0,572.36218)" /> |
1019 | + <path |
1020 | + style="color:#000000;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#Arrow1Mend-3);visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
1021 | + d="m 466.90784,282.65289 c 0,47.95865 0,47.95865 0,47.95865" |
1022 | + id="path4991" |
1023 | + inkscape:connector-curvature="0" |
1024 | + transform="translate(0,572.36218)" /> |
1025 | + <path |
1026 | + style="color:#000000;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#Arrow1Mend-3);visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
1027 | + d="m 206.1671,306.90784 c 36.38243,1.1025 65.04737,-4.40999 65.59862,-28.1137" |
1028 | + id="path4993" |
1029 | + inkscape:connector-curvature="0" |
1030 | + transform="translate(0,572.36218)" /> |
1031 | + <path |
1032 | + style="color:#000000;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#Arrow1Mend-3);visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
1033 | + d="m 245.30577,201.06804 c -47.89942,-1.36388 -68.53183,-2.05014 -70.55986,30.3187" |
1034 | + id="path4995" |
1035 | + inkscape:connector-curvature="0" |
1036 | + transform="translate(0,572.36218)" |
1037 | + sodipodi:nodetypes="cc" /> |
1038 | + <text |
1039 | + xml:space="preserve" |
1040 | + style="font-size:14px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Ubuntu;-inkscape-font-specification:Ubuntu Italic" |
1041 | + x="478.94144" |
1042 | + y="875.39905" |
1043 | + id="text4660-6" |
1044 | + sodipodi:linespacing="100%"><tspan |
1045 | + sodipodi:role="line" |
1046 | + x="478.94144" |
1047 | + y="875.39905" |
1048 | + id="tspan4664-5">Write</tspan><tspan |
1049 | + sodipodi:role="line" |
1050 | + x="478.94144" |
1051 | + y="889.39905" |
1052 | + id="tspan5086">Data</tspan></text> |
1053 | + <text |
1054 | + xml:space="preserve" |
1055 | + style="font-size:14px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Ubuntu;-inkscape-font-specification:Ubuntu Italic" |
1056 | + x="150.39708" |
1057 | + y="756.32922" |
1058 | + id="text4660-8" |
1059 | + sodipodi:linespacing="100%"><tspan |
1060 | + sodipodi:role="line" |
1061 | + id="tspan4662-9" |
1062 | + x="150.39708" |
1063 | + y="756.32922">Foo Type</tspan><tspan |
1064 | + sodipodi:role="line" |
1065 | + x="150.39708" |
1066 | + y="770.32922" |
1067 | + id="tspan4664-51">Data</tspan></text> |
1068 | + <text |
1069 | + xml:space="preserve" |
1070 | + style="font-size:14px;font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Ubuntu;-inkscape-font-specification:Ubuntu Italic" |
1071 | + x="228.12317" |
1072 | + y="896.3465" |
1073 | + id="text4660-5" |
1074 | + sodipodi:linespacing="100%"><tspan |
1075 | + sodipodi:role="line" |
1076 | + id="tspan4662-2" |
1077 | + x="228.12317" |
1078 | + y="896.3465">SVG</tspan><tspan |
1079 | + sodipodi:role="line" |
1080 | + x="228.12317" |
1081 | + y="910.3465" |
1082 | + id="tspan4664-2">Data</tspan></text> |
1083 | + <g |
1084 | + id="g4469-4" |
1085 | + transform="translate(-216.05521,77.196901)"> |
1086 | + <rect |
1087 | + y="887.29889" |
1088 | + x="403.61313" |
1089 | + height="36.266827" |
1090 | + width="263.23044" |
1091 | + id="rect2985-1-7" |
1092 | + style="color:#000000;fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> |
1093 | + <text |
1094 | + sodipodi:linespacing="100%" |
1095 | + id="text3755-5-0" |
1096 | + y="908.72668" |
1097 | + x="535.85309" |
1098 | + style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:100%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Ubuntu;-inkscape-font-specification:Ubuntu" |
1099 | + xml:space="preserve"><tspan |
1100 | + id="tspan3759-8-1" |
1101 | + y="908.72668" |
1102 | + x="535.85309" |
1103 | + sodipodi:role="line">/var/cache/infographic/$(user)/bar-foo.svg</tspan></text> |
1104 | + </g> |
1105 | + <path |
1106 | + style="color:#000000;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#Arrow1Mend-3);visibility:visible;display:inline;overflow:visible;enable-background:accumulate" |
1107 | + d="m 311.45565,849.40321 c 0,0 0,25.44875 0,104.82859" |
1108 | + id="path4987-1" |
1109 | + inkscape:connector-curvature="0" |
1110 | + sodipodi:nodetypes="cc" /> |
1111 | + <path |
1112 | + style="opacity:0.75;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Mend-3)" |
1113 | + d="m 70.370939,844.37253 c 2.166628,-1.32276 4.713537,-2.01444 7.251636,-1.96937 0.948556,0.0168 1.892954,0.13391 2.84132,0.15932 0.948365,0.0254 1.915816,-0.0448 2.800631,-0.38703 1.314563,-0.5085 2.330053,-1.56575 3.265528,-2.62004 0.935476,-1.0543 1.867729,-2.16266 3.108022,-2.83223 1.101035,-0.59439 2.362684,-0.79778 3.567965,-1.13375 0.336018,-0.0937 0.669019,-0.19815 0.998313,-0.31325" |
1114 | + id="path4674-2" |
1115 | + inkscape:path-effect="#path-effect4676-6" |
1116 | + inkscape:original-d="m 70.370939,844.37253 c 3.779008,2.44344 3.122725,0.24899 7.251636,-1.96937 9.338135,-5.39137 13.295708,6.69384 5.641951,-0.22771 -8.876629,-8.68938 3.086675,-5.33288 6.37355,-5.45227 3.286867,-0.11938 3.539607,-0.60936 3.567965,-1.13375 0.02835,-0.52438 -0.167688,-1.08314 0.998313,-0.31325" |
1117 | + inkscape:connector-curvature="0" |
1118 | + sodipodi:nodetypes="ccczsc" /> |
1119 | + </g> |
1120 | +</svg> |
1121 | |
1122 | === added symlink 'include/libusermetricsoutput/InfographicList.h' |
1123 | === target is u'../../src/libusermetricsoutput/InfographicList.h' |
1124 | === modified file 'po/en_GB.po' |
1125 | --- po/en_GB.po 2014-01-09 10:17:16 +0000 |
1126 | +++ po/en_GB.po 2014-04-03 13:02:15 +0000 |
1127 | @@ -7,7 +7,7 @@ |
1128 | msgstr "" |
1129 | "Project-Id-Version: libusermetrics\n" |
1130 | "Report-Msgid-Bugs-To: \n" |
1131 | -"POT-Creation-Date: 2014-01-09 10:15+0000\n" |
1132 | +"POT-Creation-Date: 2014-02-19 16:51+0000\n" |
1133 | "PO-Revision-Date: 2013-07-05 15:09+0100\n" |
1134 | "Last-Translator: Pete Woods <pete.woods@canonical.com>\n" |
1135 | "Language-Team: British English <en@li.org>\n" |
1136 | @@ -90,6 +90,10 @@ |
1137 | #~ msgid "Attempt to update data owned by another user" |
1138 | #~ msgstr "Attempt to update data owned by another user" |
1139 | |
1140 | +#, fuzzy |
1141 | +#~ msgid "Could not locate user data" |
1142 | +#~ msgstr "Couldn't save user data" |
1143 | + |
1144 | #~ msgid "Could not open database" |
1145 | #~ msgstr "Could not open database" |
1146 | |
1147 | @@ -102,9 +106,6 @@ |
1148 | #~ msgid "Could not save data source" |
1149 | #~ msgstr "Couldn't save data source" |
1150 | |
1151 | -#~ msgid "Could not save user data" |
1152 | -#~ msgstr "Couldn't save user data" |
1153 | - |
1154 | #~ msgid "Data set query failed" |
1155 | #~ msgstr "Data set query failed" |
1156 | |
1157 | |
1158 | === modified file 'po/libusermetrics.pot' |
1159 | --- po/libusermetrics.pot 2014-01-09 10:17:16 +0000 |
1160 | +++ po/libusermetrics.pot 2014-04-03 13:02:15 +0000 |
1161 | @@ -8,7 +8,7 @@ |
1162 | msgstr "" |
1163 | "Project-Id-Version: libusermetrics\n" |
1164 | "Report-Msgid-Bugs-To: \n" |
1165 | -"POT-Creation-Date: 2014-01-09 10:15+0000\n" |
1166 | +"POT-Creation-Date: 2014-03-02 20:57+0000\n" |
1167 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" |
1168 | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" |
1169 | "Language-Team: LANGUAGE <LL@li.org>\n" |
1170 | |
1171 | === modified file 'src/CMakeLists.txt' |
1172 | --- src/CMakeLists.txt 2014-01-08 18:15:21 +0000 |
1173 | +++ src/CMakeLists.txt 2014-04-03 13:02:15 +0000 |
1174 | @@ -7,6 +7,7 @@ |
1175 | add_compiler_export_flags() |
1176 | |
1177 | add_subdirectory("infographic") |
1178 | +add_subdirectory("infographicservice") |
1179 | add_subdirectory("libusermetricscommon") |
1180 | add_subdirectory("libusermetricsinput") |
1181 | add_subdirectory("libusermetricsoutput") |
1182 | |
1183 | === modified file 'src/infographic/CMakeLists.txt' |
1184 | --- src/infographic/CMakeLists.txt 2014-01-08 18:15:21 +0000 |
1185 | +++ src/infographic/CMakeLists.txt 2014-04-03 13:02:15 +0000 |
1186 | @@ -10,8 +10,8 @@ |
1187 | ) |
1188 | |
1189 | install( |
1190 | - TARGETS infographic |
1191 | - RUNTIME DESTINATION bin |
1192 | + TARGETS infographic |
1193 | + RUNTIME DESTINATION "${CMAKE_INSTALL_FULL_LIBEXECDIR}/libusermetrics" |
1194 | ) |
1195 | |
1196 | qt5_use_modules( |
1197 | |
1198 | === modified file 'src/infographic/main.cpp' |
1199 | --- src/infographic/main.cpp 2014-01-08 18:15:21 +0000 |
1200 | +++ src/infographic/main.cpp 2014-04-03 13:02:15 +0000 |
1201 | @@ -28,16 +28,21 @@ |
1202 | int main(int argc, char *argv[]) { |
1203 | QCoreApplication application(argc, argv); |
1204 | |
1205 | - if (argc != 3) { |
1206 | - qWarning() << "Usage: " << argv[0] << "INPUT_FILE OUTPUT_FILE"; |
1207 | + if (argc < 2) { |
1208 | + qWarning() << "Usage: " << argv[0] << "INPUT_FILE [OUTPUT_FILE]"; |
1209 | return 1; |
1210 | } |
1211 | |
1212 | QFile inputFile(QString::fromUtf8(argv[1])); |
1213 | - QFile outputFile(QString::fromUtf8(argv[2])); |
1214 | + QFile outputFile; |
1215 | + if (argc == 3) { |
1216 | + outputFile.setFileName(QString::fromUtf8(argv[2])); |
1217 | + outputFile.open(QIODevice::WriteOnly); |
1218 | + } else { |
1219 | + outputFile.open(1, QIODevice::WriteOnly); |
1220 | + } |
1221 | |
1222 | inputFile.open(QIODevice::ReadOnly); |
1223 | - outputFile.open(QIODevice::WriteOnly); |
1224 | |
1225 | Infographic infographic(inputFile, outputFile); |
1226 | |
1227 | |
1228 | === added directory 'src/infographicservice' |
1229 | === added file 'src/infographicservice/CMakeLists.txt' |
1230 | --- src/infographicservice/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
1231 | +++ src/infographicservice/CMakeLists.txt 2014-04-03 13:02:15 +0000 |
1232 | @@ -0,0 +1,58 @@ |
1233 | + |
1234 | +set(INFOGRAPHICSERVICE_SOURCES |
1235 | + Service.cpp |
1236 | +) |
1237 | + |
1238 | +qt5_add_dbus_adaptor( |
1239 | + INFOGRAPHICSERVICE_SOURCES |
1240 | + ${INFOGRAPHIC_SERVICE_XML} |
1241 | + infographicservice/Service.h |
1242 | + InfographicService::Service |
1243 | + InfographicServiceAdaptor |
1244 | +) |
1245 | + |
1246 | +add_library( |
1247 | + infographicservice |
1248 | + STATIC |
1249 | + ${INFOGRAPHICSERVICE_SOURCES} |
1250 | +) |
1251 | + |
1252 | +qt5_use_modules( |
1253 | + infographicservice |
1254 | + Core |
1255 | + DBus |
1256 | +) |
1257 | + |
1258 | +############################ |
1259 | +# Service executable |
1260 | +############################ |
1261 | + |
1262 | +add_executable( |
1263 | + infographicservice-bin |
1264 | + main.cpp |
1265 | +) |
1266 | + |
1267 | +set_target_properties( |
1268 | + infographicservice-bin |
1269 | + PROPERTIES |
1270 | + OUTPUT_NAME "infographicservice" |
1271 | +) |
1272 | + |
1273 | +target_link_libraries( |
1274 | + infographicservice-bin |
1275 | + infographicservice |
1276 | +) |
1277 | + |
1278 | +qt5_use_modules( |
1279 | + infographicservice-bin |
1280 | + Core |
1281 | +) |
1282 | + |
1283 | +######################### |
1284 | +# Installation |
1285 | +######################### |
1286 | + |
1287 | +install( |
1288 | + TARGETS infographicservice-bin |
1289 | + RUNTIME DESTINATION "${CMAKE_INSTALL_FULL_LIBEXECDIR}/libusermetrics" |
1290 | +) |
1291 | |
1292 | === added file 'src/infographicservice/Service.cpp' |
1293 | --- src/infographicservice/Service.cpp 1970-01-01 00:00:00 +0000 |
1294 | +++ src/infographicservice/Service.cpp 2014-04-03 13:02:15 +0000 |
1295 | @@ -0,0 +1,131 @@ |
1296 | +/* |
1297 | + * Service.cpp |
1298 | + * |
1299 | + * Created on: 2 Mar 2014 |
1300 | + * Author: pete |
1301 | + */ |
1302 | + |
1303 | +#include <infographicservice/InfographicServiceAdaptor.h> |
1304 | +#include <infographicservice/Service.h> |
1305 | +#include <libusermetricscommon/DBusPaths.h> |
1306 | + |
1307 | +#include <QDateTime> |
1308 | +#include <QFile> |
1309 | +#include <cstdio> |
1310 | + |
1311 | +using namespace InfographicService; |
1312 | +using namespace UserMetricsCommon; |
1313 | + |
1314 | +Service::Service(const QDir &directory, const QDBusConnection &systemConnection) : |
1315 | + m_directory(directory), m_connection(systemConnection), m_adaptor( |
1316 | + new InfographicsAdaptor(this)), m_hash(QCryptographicHash::Sha1) { |
1317 | + |
1318 | + m_dirtyTimer.setSingleShot(true); |
1319 | + m_dirtyTimer.setTimerType(Qt::VeryCoarseTimer); |
1320 | + connect(&m_dirtyTimer, &QTimer::timeout, this, &Service::timeout); |
1321 | + |
1322 | + m_directory.mkpath("tmp"); |
1323 | + m_tempFile.setFileName( |
1324 | + QDir(m_directory.filePath("tmp")).filePath("tmp.svg")); |
1325 | + |
1326 | + if (!m_connection.registerObject(DBusPaths::INFOGRAPHIC_DBUS_PATH, this)) { |
1327 | + throw std::logic_error( |
1328 | + "Unable to register Infographics object on DBus"); |
1329 | + } |
1330 | + if (!m_connection.registerService(DBusPaths::INFOGRAPHIC_DBUS_NAME)) { |
1331 | + throw std::logic_error( |
1332 | + "Unable to register Infographics service on DBus"); |
1333 | + } |
1334 | +} |
1335 | + |
1336 | +Service::~Service() { |
1337 | + m_connection.unregisterService(DBusPaths::INFOGRAPHIC_DBUS_NAME); |
1338 | + m_connection.unregisterObject(DBusPaths::INFOGRAPHIC_DBUS_PATH); |
1339 | +} |
1340 | + |
1341 | +unsigned int Service::uid() { |
1342 | + if (!calledFromDBus()) { |
1343 | + return 0; |
1344 | + } |
1345 | + |
1346 | + return m_connection.interface()->serviceUid(message().service()); |
1347 | +} |
1348 | + |
1349 | +QDir Service::userDirectory() { |
1350 | + return m_directory.filePath(QString::number(uid())); |
1351 | +} |
1352 | + |
1353 | +void Service::clear() { |
1354 | + userDirectory().removeRecursively(); |
1355 | +} |
1356 | + |
1357 | +void Service::update(const QString &visualizer, const QStringList &sources, |
1358 | + const QString &filePath) { |
1359 | + |
1360 | + m_hash.reset(); |
1361 | + m_hash.addData(visualizer.toUtf8()); |
1362 | + for (const QString &source : sources) { |
1363 | + m_hash.addData(source.toUtf8()); |
1364 | + } |
1365 | + |
1366 | + QString sha(m_hash.result().toHex()); |
1367 | + |
1368 | + QDir usersDirectory(userDirectory()); |
1369 | + QDir infographicDirectory(usersDirectory.filePath(visualizer)); |
1370 | + QString destination(infographicDirectory.filePath(sha)); |
1371 | + destination.append("-"); |
1372 | + destination.append(QString::number(QDateTime::currentMSecsSinceEpoch())); |
1373 | + destination.append(".svg"); |
1374 | + |
1375 | + QFile file(filePath); |
1376 | + QByteArray ba; |
1377 | + if (file.open(QIODevice::ReadOnly)) { |
1378 | + ba = file.readAll(); |
1379 | + file.close(); |
1380 | + } else { |
1381 | + qWarning() << "Failed to open file" << filePath; |
1382 | + return; |
1383 | + } |
1384 | + |
1385 | + if (ba.isEmpty()) { |
1386 | + return; |
1387 | + } |
1388 | + |
1389 | + usersDirectory.mkpath(visualizer); |
1390 | + if (m_tempFile.open(QIODevice::WriteOnly)) { |
1391 | + m_tempFile.write(ba); |
1392 | + m_tempFile.close(); |
1393 | + } else { |
1394 | + qWarning() << "Failed to write file" << m_tempFile.fileName(); |
1395 | + } |
1396 | + |
1397 | + int result = std::rename(m_tempFile.fileName().toUtf8().constData(), |
1398 | + destination.toUtf8().constData()); |
1399 | + if (result == -1) { |
1400 | + qWarning() << "Failed to move result" << m_tempFile.fileName() |
1401 | + << "to destination" << destination; |
1402 | + return; |
1403 | + } |
1404 | + |
1405 | + // clean up in one minute |
1406 | + m_dirty << qMakePair(infographicDirectory.path(), sha + "-*.svg"); |
1407 | + m_dirtyTimer.start(60000); |
1408 | +} |
1409 | + |
1410 | +void Service::timeout() { |
1411 | + for (const QPair<QString, QString> &result : m_dirty) { |
1412 | + QDir infographicDirectory(result.first); |
1413 | + |
1414 | + QStringList entries = infographicDirectory.entryList( |
1415 | + QStringList() << result.second, |
1416 | + QDir::Files | QDir::NoDotAndDotDot, QDir::Name); |
1417 | + |
1418 | + // We don't want to delete the last entry |
1419 | + entries.pop_back(); |
1420 | + for (const QString &entry : entries) { |
1421 | + QFile::remove(infographicDirectory.filePath(entry)); |
1422 | + } |
1423 | + } |
1424 | + |
1425 | + m_dirty.clear(); |
1426 | +} |
1427 | |
1428 | === added file 'src/infographicservice/Service.h' |
1429 | --- src/infographicservice/Service.h 1970-01-01 00:00:00 +0000 |
1430 | +++ src/infographicservice/Service.h 2014-04-03 13:02:15 +0000 |
1431 | @@ -0,0 +1,74 @@ |
1432 | +/* |
1433 | + * Copyright (C) 2014 Canonical, Ltd. |
1434 | + * |
1435 | + * This program is free software; you can redistribute it and/or modify |
1436 | + * it under the terms of the GNU General Public License as published by |
1437 | + * the Free Software Foundation; version 3. |
1438 | + * |
1439 | + * This program is distributed in the hope that it will be useful, |
1440 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1441 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1442 | + * GNU General Public License for more details. |
1443 | + * |
1444 | + * You should have received a copy of the GNU General Public License |
1445 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1446 | + * |
1447 | + * Author: Pete Woods <pete.woods@canonical.com> |
1448 | + */ |
1449 | + |
1450 | +#ifndef INFOGRAPHICSERVICE_SERVICE_H_ |
1451 | +#define INFOGRAPHICSERVICE_SERVICE_H_ |
1452 | + |
1453 | +#include <QCryptographicHash> |
1454 | +#include <QDir> |
1455 | +#include <QDBusContext> |
1456 | +#include <QDBusConnection> |
1457 | +#include <QObject> |
1458 | +#include <QSet> |
1459 | +#include <QSharedPointer> |
1460 | +#include <QTimer> |
1461 | + |
1462 | +class InfographicsAdaptor; |
1463 | + |
1464 | +namespace InfographicService { |
1465 | + |
1466 | +class Service: public QObject, protected QDBusContext { |
1467 | +Q_OBJECT |
1468 | + |
1469 | +public: |
1470 | + Service(const QDir &directory, const QDBusConnection &systemConnection); |
1471 | + |
1472 | + virtual ~Service(); |
1473 | + |
1474 | +public Q_SLOTS: |
1475 | + void clear(); |
1476 | + |
1477 | + void update(const QString &visualizer, const QStringList &sources, |
1478 | + const QString &file); |
1479 | + |
1480 | +protected Q_SLOTS: |
1481 | + void timeout(); |
1482 | + |
1483 | +protected: |
1484 | + virtual unsigned int uid(); |
1485 | + |
1486 | + QDir userDirectory(); |
1487 | + |
1488 | + QDir m_directory; |
1489 | + |
1490 | + QFile m_tempFile; |
1491 | + |
1492 | + QDBusConnection m_connection; |
1493 | + |
1494 | + QSharedPointer<InfographicsAdaptor> m_adaptor; |
1495 | + |
1496 | + QTimer m_dirtyTimer; |
1497 | + |
1498 | + QCryptographicHash m_hash; |
1499 | + |
1500 | + QSet<QPair<QString, QString>> m_dirty; |
1501 | +}; |
1502 | + |
1503 | +} |
1504 | + |
1505 | +#endif /* INFOGRAPHICSERVICE_SERVICE_H_ */ |
1506 | |
1507 | === added file 'src/infographicservice/main.cpp' |
1508 | --- src/infographicservice/main.cpp 1970-01-01 00:00:00 +0000 |
1509 | +++ src/infographicservice/main.cpp 2014-04-03 13:02:15 +0000 |
1510 | @@ -0,0 +1,46 @@ |
1511 | +/* |
1512 | + * Copyright (C) 2014 Canonical, Ltd. |
1513 | + * |
1514 | + * This program is free software; you can redistribute it and/or modify |
1515 | + * it under the terms of the GNU General Public License as published by |
1516 | + * the Free Software Foundation; version 3. |
1517 | + * |
1518 | + * This program is distributed in the hope that it will be useful, |
1519 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1520 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1521 | + * GNU General Public License for more details. |
1522 | + * |
1523 | + * You should have received a copy of the GNU General Public License |
1524 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1525 | + * |
1526 | + * Author: Pete Woods <pete.woods@canonical.com> |
1527 | + */ |
1528 | + |
1529 | +#include <infographicservice/Service.h> |
1530 | + |
1531 | +#include <QCoreApplication> |
1532 | +#include <QDebug> |
1533 | +#include <csignal> |
1534 | + |
1535 | +using namespace InfographicService; |
1536 | + |
1537 | +static void exitQt(int sig) { |
1538 | + Q_UNUSED(sig); |
1539 | + QCoreApplication::exit(0); |
1540 | +} |
1541 | + |
1542 | +int main(int argc, char *argv[]) { |
1543 | + QCoreApplication application(argc, argv); |
1544 | + |
1545 | + signal(SIGINT, &exitQt); |
1546 | + signal(SIGTERM, &exitQt); |
1547 | + |
1548 | + try { |
1549 | + Service service(QDir("/var/lib/usermetrics"), |
1550 | + QDBusConnection::systemBus()); |
1551 | + return application.exec(); |
1552 | + } catch (std::exception &e) { |
1553 | + qWarning() << "Infographic Service:" << e.what(); |
1554 | + return 1; |
1555 | + } |
1556 | +} |
1557 | |
1558 | === modified file 'src/libusermetricscommon/CMakeLists.txt' |
1559 | --- src/libusermetricscommon/CMakeLists.txt 2014-01-03 11:40:22 +0000 |
1560 | +++ src/libusermetricscommon/CMakeLists.txt 2014-04-03 13:02:15 +0000 |
1561 | @@ -2,9 +2,16 @@ |
1562 | set(USERMETRICS_COMMON_SOURCES |
1563 | DateFactory.cpp |
1564 | DateFactoryImpl.cpp |
1565 | + FileUtils.cpp |
1566 | Localisation.cpp |
1567 | ) |
1568 | |
1569 | +qt5_add_dbus_interface( |
1570 | + USERMETRICS_COMMON_SOURCES |
1571 | + ${INFOGRAPHIC_SERVICE_XML} |
1572 | + InfographicsInterface |
1573 | +) |
1574 | + |
1575 | add_library( |
1576 | usermetricscommon |
1577 | STATIC |
1578 | @@ -14,5 +21,5 @@ |
1579 | qt5_use_modules( |
1580 | usermetricscommon |
1581 | Core |
1582 | + DBus |
1583 | ) |
1584 | - |
1585 | |
1586 | === added file 'src/libusermetricscommon/DBusPaths.h' |
1587 | --- src/libusermetricscommon/DBusPaths.h 1970-01-01 00:00:00 +0000 |
1588 | +++ src/libusermetricscommon/DBusPaths.h 2014-04-03 13:02:15 +0000 |
1589 | @@ -0,0 +1,37 @@ |
1590 | +/* |
1591 | + * Copyright (C) 2013 Canonical, Ltd. |
1592 | + * |
1593 | + * This library is free software; you can redistribute it and/or modify it under |
1594 | + * the terms of version 3 of the GNU Lesser General Public License as published |
1595 | + * by the Free Software Foundation. |
1596 | + * |
1597 | + * This library is distributed in the hope that it will be useful, but WITHOUT |
1598 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
1599 | + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
1600 | + * details. |
1601 | + * |
1602 | + * You should have received a copy of the GNU Lesser General Public License |
1603 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1604 | + * |
1605 | + * Author: Pete Woods <pete.woods@canonical.com> |
1606 | + */ |
1607 | + |
1608 | +#ifndef USERMETRICSCOMMON_DBUSPATHS_H_ |
1609 | +#define USERMETRICSCOMMON_DBUSPATHS_H_ |
1610 | + |
1611 | +#include <QtCore/QString> |
1612 | + |
1613 | +namespace UserMetricsCommon { |
1614 | + |
1615 | +class DBusPaths { |
1616 | +public: |
1617 | + constexpr static const char* INFOGRAPHIC_DBUS_NAME = |
1618 | + "com.canonical.Infographics"; |
1619 | + |
1620 | + constexpr static const char* INFOGRAPHIC_DBUS_PATH = |
1621 | + "/com/canonical/Infographics"; |
1622 | +}; |
1623 | + |
1624 | +} |
1625 | + |
1626 | +#endif // USERMETRICSCOMMON_DBUSPATHS_H_ |
1627 | |
1628 | === added file 'src/libusermetricscommon/FileUtils.cpp' |
1629 | --- src/libusermetricscommon/FileUtils.cpp 1970-01-01 00:00:00 +0000 |
1630 | +++ src/libusermetricscommon/FileUtils.cpp 2014-04-03 13:02:15 +0000 |
1631 | @@ -0,0 +1,52 @@ |
1632 | +/* |
1633 | + * Copyright (C) 2014 Canonical, Ltd. |
1634 | + * |
1635 | + * This program is free software; you can redistribute it and/or modify |
1636 | + * it under the terms of the GNU General Public License as published by |
1637 | + * the Free Software Foundation; version 3. |
1638 | + * |
1639 | + * This program is distributed in the hope that it will be useful, |
1640 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1641 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1642 | + * GNU General Public License for more details. |
1643 | + * |
1644 | + * You should have received a copy of the GNU General Public License |
1645 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1646 | + * |
1647 | + * Author: Pete Woods <pete.woods@canonical.com> |
1648 | + */ |
1649 | + |
1650 | +#include <libusermetricscommon/FileUtils.h> |
1651 | + |
1652 | +#include <QRegularExpression> |
1653 | + |
1654 | +using namespace UserMetricsCommon; |
1655 | + |
1656 | +QRegularExpression FileUtils::CLICK_REGEX( |
1657 | + "^[a-z0-9][a-z0-9+.-]+_[a-zA-Z0-9+.-]+_[0-9][a-zA-Z0-9.+:~-]*$"); |
1658 | + |
1659 | +FileUtils::FileUtils() { |
1660 | +} |
1661 | + |
1662 | +FileUtils::~FileUtils() { |
1663 | +} |
1664 | + |
1665 | +QStringList FileUtils::listDirectory(const QDir &directory, |
1666 | + QDir::Filters filters, QDir::SortFlags sort) { |
1667 | + QStringList names; |
1668 | + for (const QString& name : directory.entryList( |
1669 | + filters | QDir::NoDotAndDotDot, sort)) { |
1670 | + names << directory.filePath(name); |
1671 | + } |
1672 | + return names; |
1673 | +} |
1674 | + |
1675 | +void FileUtils::shortApplicationId(QString &applicationId) { |
1676 | + QRegularExpressionMatch match = CLICK_REGEX.match(applicationId); |
1677 | + if (match.hasMatch()) { |
1678 | + int index = applicationId.indexOf('_'); |
1679 | + if (index != -1) { |
1680 | + applicationId.remove(index, applicationId.size()); |
1681 | + } |
1682 | + } |
1683 | +} |
1684 | |
1685 | === added file 'src/libusermetricscommon/FileUtils.h' |
1686 | --- src/libusermetricscommon/FileUtils.h 1970-01-01 00:00:00 +0000 |
1687 | +++ src/libusermetricscommon/FileUtils.h 2014-04-03 13:02:15 +0000 |
1688 | @@ -0,0 +1,47 @@ |
1689 | +/* |
1690 | + * Copyright (C) 2014 Canonical, Ltd. |
1691 | + * |
1692 | + * This program is free software; you can redistribute it and/or modify |
1693 | + * it under the terms of the GNU General Public License as published by |
1694 | + * the Free Software Foundation; version 3. |
1695 | + * |
1696 | + * This program is distributed in the hope that it will be useful, |
1697 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1698 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1699 | + * GNU General Public License for more details. |
1700 | + * |
1701 | + * You should have received a copy of the GNU General Public License |
1702 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1703 | + * |
1704 | + * Author: Pete Woods <pete.woods@canonical.com> |
1705 | + */ |
1706 | + |
1707 | +#ifndef USERMETRICSCOMMON_FILEUTILS_H_ |
1708 | +#define USERMETRICSCOMMON_FILEUTILS_H_ |
1709 | + |
1710 | +#include <QDir> |
1711 | +#include <QSet> |
1712 | +#include <QSharedPointer> |
1713 | +#include <QStringList> |
1714 | + |
1715 | +namespace UserMetricsCommon { |
1716 | + |
1717 | +class FileUtils { |
1718 | +public: |
1719 | + typedef QSharedPointer<FileUtils> Ptr; |
1720 | + |
1721 | + FileUtils(); |
1722 | + |
1723 | + virtual ~FileUtils(); |
1724 | + |
1725 | + static QRegularExpression CLICK_REGEX; |
1726 | + |
1727 | + virtual QStringList listDirectory(const QDir &directory, |
1728 | + QDir::Filters filters, QDir::SortFlags sort = QDir::NoSort); |
1729 | + |
1730 | + void shortApplicationId(QString &applicationId); |
1731 | +}; |
1732 | + |
1733 | +} |
1734 | + |
1735 | +#endif /* USERMETRICSCOMMON_FILEUTILS_H_ */ |
1736 | |
1737 | === modified file 'src/libusermetricsinput/MetricImpl.cpp' |
1738 | --- src/libusermetricsinput/MetricImpl.cpp 2014-01-06 17:31:49 +0000 |
1739 | +++ src/libusermetricsinput/MetricImpl.cpp 2014-04-03 13:02:15 +0000 |
1740 | @@ -17,6 +17,7 @@ |
1741 | */ |
1742 | |
1743 | #include <stdexcept> |
1744 | +#include <cstdio> |
1745 | |
1746 | #include <libusermetricscommon/Localisation.h> |
1747 | #include <libusermetricsinput/MetricImpl.h> |
1748 | @@ -183,7 +184,13 @@ |
1749 | } |
1750 | |
1751 | QString MetricImpl::buildJsonFile() { |
1752 | - return m_metricDirectory.filePath(m_parameters.id() + ".json"); |
1753 | + return m_metricDirectory.filePath( |
1754 | + m_parameters.id() + ".libusermetrics.json"); |
1755 | +} |
1756 | + |
1757 | +QString MetricImpl::buildTmpFile() { |
1758 | + return QDir(m_metricDirectory.filePath(".tmp")).filePath( |
1759 | + "." + m_parameters.id() + ".libusermetrics.json"); |
1760 | } |
1761 | |
1762 | void MetricImpl::loadData() { |
1763 | @@ -241,11 +248,21 @@ |
1764 | |
1765 | QJsonDocument document(QJsonDocument::fromVariant(root)); |
1766 | |
1767 | - QFile jsonFile(buildJsonFile()); |
1768 | - if (jsonFile.open(QIODevice::WriteOnly)) { |
1769 | - jsonFile.write(document.toJson()); |
1770 | - jsonFile.close(); |
1771 | + m_metricDirectory.mkpath(".tmp"); |
1772 | + QFile tmpFile(buildTmpFile()); |
1773 | + if (tmpFile.open(QIODevice::WriteOnly)) { |
1774 | + tmpFile.write(document.toJson()); |
1775 | + tmpFile.close(); |
1776 | } else { |
1777 | - qWarning() << "Could not write usermetrics file" << jsonFile.fileName(); |
1778 | + qWarning() << "Could not write usermetrics file" << tmpFile.fileName(); |
1779 | + return; |
1780 | + } |
1781 | + |
1782 | + QString jsonFile(buildJsonFile()); |
1783 | + int result = std::rename(tmpFile.fileName().toUtf8().constData(), |
1784 | + jsonFile.toUtf8().constData()); |
1785 | + if (result == -1) { |
1786 | + qWarning() << "Failed to move result" << tmpFile.fileName() |
1787 | + << "to destination" << jsonFile; |
1788 | } |
1789 | } |
1790 | |
1791 | === modified file 'src/libusermetricsinput/MetricImpl.h' |
1792 | --- src/libusermetricsinput/MetricImpl.h 2014-01-06 11:25:07 +0000 |
1793 | +++ src/libusermetricsinput/MetricImpl.h 2014-04-03 13:02:15 +0000 |
1794 | @@ -63,6 +63,8 @@ |
1795 | |
1796 | QString buildJsonFile(); |
1797 | |
1798 | + QString buildTmpFile(); |
1799 | + |
1800 | QDir m_metricDirectory; |
1801 | |
1802 | MetricParameters m_parameters; |
1803 | |
1804 | === modified file 'src/libusermetricsinput/MetricManagerImpl.cpp' |
1805 | --- src/libusermetricsinput/MetricManagerImpl.cpp 2014-01-06 17:31:49 +0000 |
1806 | +++ src/libusermetricsinput/MetricManagerImpl.cpp 2014-04-03 13:02:15 +0000 |
1807 | @@ -16,14 +16,28 @@ |
1808 | * Author: Pete Woods <pete.woods@canonical.com> |
1809 | */ |
1810 | |
1811 | +#include <libusermetricscommon/FileUtils.h> |
1812 | #include <libusermetricsinput/MetricImpl.h> |
1813 | #include <libusermetricsinput/MetricManagerImpl.h> |
1814 | |
1815 | #include <stdexcept> |
1816 | #include <QDebug> |
1817 | +#include <QRegularExpression> |
1818 | + |
1819 | |
1820 | using namespace std; |
1821 | using namespace UserMetricsInput; |
1822 | +using namespace UserMetricsCommon; |
1823 | + |
1824 | +static void shortApplicationId(QString &applicationId) { |
1825 | + QRegularExpressionMatch match = FileUtils::CLICK_REGEX.match(applicationId); |
1826 | + if (match.hasMatch()) { |
1827 | + int index = applicationId.indexOf('_'); |
1828 | + if (index != -1) { |
1829 | + applicationId.remove(index, applicationId.size()); |
1830 | + } |
1831 | + } |
1832 | +} |
1833 | |
1834 | MetricManagerImpl::MetricManagerImpl(Factory::Ptr factory, |
1835 | const QDir &cacheDirectory, const QString &applicationId, |
1836 | @@ -32,7 +46,11 @@ |
1837 | if (applicationId.isEmpty()) { |
1838 | throw logic_error("Invalid application ID"); |
1839 | } |
1840 | - QDir applicationDirectory(cacheDirectory.filePath(applicationId)); |
1841 | + |
1842 | + QString shortId(applicationId); |
1843 | + shortApplicationId(shortId); |
1844 | + |
1845 | + QDir applicationDirectory(cacheDirectory.filePath(shortId)); |
1846 | if (!applicationDirectory.mkpath("usermetrics")) { |
1847 | throw logic_error("Cannot write to cache directory"); |
1848 | } |
1849 | |
1850 | === modified file 'src/libusermetricsoutput/CMakeLists.txt' |
1851 | --- src/libusermetricsoutput/CMakeLists.txt 2014-01-03 11:40:22 +0000 |
1852 | +++ src/libusermetricsoutput/CMakeLists.txt 2014-04-03 13:02:15 +0000 |
1853 | @@ -12,6 +12,9 @@ |
1854 | GSettingsColorThemeProvider.cpp |
1855 | DataSet.cpp |
1856 | DataSource.cpp |
1857 | + DirectoryWatcher.cpp |
1858 | + InfographicList.cpp |
1859 | + InfographicListImpl.cpp |
1860 | UserData.cpp |
1861 | UserMetrics.cpp |
1862 | UserMetricsImpl.cpp |
1863 | |
1864 | === added file 'src/libusermetricsoutput/DirectoryWatcher.cpp' |
1865 | --- src/libusermetricsoutput/DirectoryWatcher.cpp 1970-01-01 00:00:00 +0000 |
1866 | +++ src/libusermetricsoutput/DirectoryWatcher.cpp 2014-04-03 13:02:15 +0000 |
1867 | @@ -0,0 +1,114 @@ |
1868 | +/* |
1869 | + * Copyright (C) 2014 Canonical, Ltd. |
1870 | + * |
1871 | + * This library is free software; you can redistribute it and/or modify it under |
1872 | + * the terms of version 3 of the GNU Lesser General Public License as published |
1873 | + * by the Free Software Foundation. |
1874 | + * |
1875 | + * This library is distributed in the hope that it will be useful, but WITHOUT |
1876 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
1877 | + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
1878 | + * details. |
1879 | + * |
1880 | + * You should have received a copy of the GNU Lesser General Public License |
1881 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1882 | + * |
1883 | + * Author: Pete Woods <pete.woods@canonical.com> |
1884 | + */ |
1885 | + |
1886 | +#include <libusermetricsoutput/DirectoryWatcher.h> |
1887 | + |
1888 | +#include <QDebug> |
1889 | + |
1890 | +using namespace UserMetricsCommon; |
1891 | +using namespace UserMetricsOutput; |
1892 | + |
1893 | +namespace { |
1894 | + |
1895 | +static bool nameCompare(const QString &a, const QString &b) { |
1896 | + int indexA = a.lastIndexOf('-'); |
1897 | + int indexB = b.lastIndexOf('-'); |
1898 | + |
1899 | + if (indexA == -1 || indexB == -1) { |
1900 | + return false; |
1901 | + } |
1902 | + |
1903 | + QStringRef startA = a.leftRef(indexA); |
1904 | + QStringRef startB = b.leftRef(indexB); |
1905 | + |
1906 | + return !!startA.compare(startB); |
1907 | +} |
1908 | + |
1909 | +} |
1910 | + |
1911 | +DirectoryWatcher::DirectoryWatcher(const QDir &path, unsigned int maxDepth, |
1912 | + FileUtils::Ptr fileUtils) : |
1913 | + m_path(path), m_maxDepth(maxDepth), m_fileUtils(fileUtils) { |
1914 | + |
1915 | + m_watcher.addPath(path.path()); |
1916 | + |
1917 | + connect(&m_watcher, &QFileSystemWatcher::directoryChanged, this, |
1918 | + &DirectoryWatcher::internalDirectoryChanged); |
1919 | +} |
1920 | + |
1921 | +DirectoryWatcher::~DirectoryWatcher() { |
1922 | +} |
1923 | + |
1924 | +void DirectoryWatcher::start() { |
1925 | + internalDirectoryChanged(); |
1926 | +} |
1927 | + |
1928 | +void DirectoryWatcher::internalDirectoryChanged() { |
1929 | + QStringList files( |
1930 | + m_fileUtils->listDirectory(m_path, QDir::Files, QDir::Name)); |
1931 | + |
1932 | + QStringList newestFiles; |
1933 | + |
1934 | + const QString *previous(nullptr); |
1935 | + for (const QString &file : files) { |
1936 | + if (!previous) { |
1937 | + previous = &file; |
1938 | + } else if (nameCompare(*previous, file)) { |
1939 | + newestFiles << *previous; |
1940 | + } |
1941 | + previous = &file; |
1942 | + } |
1943 | + |
1944 | + if (previous) { |
1945 | + newestFiles << *previous; |
1946 | + } |
1947 | + |
1948 | + directoryChanged(m_path.path(), newestFiles); |
1949 | + |
1950 | + if (m_maxDepth == 0) { |
1951 | + return; |
1952 | + } |
1953 | + |
1954 | + QSet<QString> directories( |
1955 | + m_fileUtils->listDirectory(m_path, QDir::Dirs).toSet()); |
1956 | + |
1957 | + // Remove deleted files |
1958 | + QSet<QString> directoriesToRemove( |
1959 | + m_directories.keys().toSet().subtract(directories)); |
1960 | + for (const QString &name : directoriesToRemove) { |
1961 | + m_directories.remove(name); |
1962 | + directoryRemoved(name); |
1963 | + } |
1964 | + |
1965 | + // Work out the names we need to add |
1966 | + directories.subtract(m_directories.keys().toSet()); |
1967 | + for (const QString &name : directories) { |
1968 | + DirectoryWatcher::Ptr watcher( |
1969 | + new DirectoryWatcher(name, m_maxDepth - 1, m_fileUtils)); |
1970 | + m_directories.insert(name, watcher); |
1971 | + connect(watcher.data(), &DirectoryWatcher::directoryChanged, this, |
1972 | + &DirectoryWatcher::directoryChanged); |
1973 | + connect(watcher.data(), &DirectoryWatcher::directoryRemoved, this, |
1974 | + &DirectoryWatcher::directoryRemoved); |
1975 | + watcher->start(); |
1976 | + } |
1977 | +} |
1978 | + |
1979 | +QStringList DirectoryWatcher::files() { |
1980 | + return m_watcher.files(); |
1981 | +} |
1982 | |
1983 | === added file 'src/libusermetricsoutput/DirectoryWatcher.h' |
1984 | --- src/libusermetricsoutput/DirectoryWatcher.h 1970-01-01 00:00:00 +0000 |
1985 | +++ src/libusermetricsoutput/DirectoryWatcher.h 2014-04-03 13:02:15 +0000 |
1986 | @@ -0,0 +1,69 @@ |
1987 | +/* |
1988 | + * Copyright (C) 2014 Canonical, Ltd. |
1989 | + * |
1990 | + * This library is free software; you can redistribute it and/or modify it under |
1991 | + * the terms of version 3 of the GNU Lesser General Public License as published |
1992 | + * by the Free Software Foundation. |
1993 | + * |
1994 | + * This library is distributed in the hope that it will be useful, but WITHOUT |
1995 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
1996 | + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
1997 | + * details. |
1998 | + * |
1999 | + * You should have received a copy of the GNU Lesser General Public License |
2000 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2001 | + * |
2002 | + * Author: Pete Woods <pete.woods@canonical.com> |
2003 | + */ |
2004 | + |
2005 | +#ifndef USERMETRICSOUTPUT_DIRECTORYWATCHER_H_ |
2006 | +#define USERMETRICSOUTPUT_DIRECTORYWATCHER_H_ |
2007 | + |
2008 | +#include <libusermetricscommon/FileUtils.h> |
2009 | + |
2010 | +#include <QDir> |
2011 | +#include <QMap> |
2012 | +#include <QFileSystemWatcher> |
2013 | +#include <QSharedPointer> |
2014 | + |
2015 | +namespace UserMetricsOutput { |
2016 | + |
2017 | +class DirectoryWatcher: public QObject { |
2018 | +Q_OBJECT |
2019 | + |
2020 | +public: |
2021 | + typedef QSharedPointer<DirectoryWatcher> Ptr; |
2022 | + |
2023 | + DirectoryWatcher(const QDir &path, unsigned int maxDepth, |
2024 | + UserMetricsCommon::FileUtils::Ptr fileUtils); |
2025 | + |
2026 | + virtual ~DirectoryWatcher(); |
2027 | + |
2028 | + QStringList files(); |
2029 | + |
2030 | +public Q_SLOTS: |
2031 | + void start(); |
2032 | + |
2033 | +Q_SIGNALS: |
2034 | + void directoryChanged(const QString &directory, const QStringList &files); |
2035 | + |
2036 | + void directoryRemoved(const QString &directory); |
2037 | + |
2038 | +protected Q_SLOTS: |
2039 | + void internalDirectoryChanged(); |
2040 | + |
2041 | +protected: |
2042 | + QDir m_path; |
2043 | + |
2044 | + unsigned int m_maxDepth; |
2045 | + |
2046 | + UserMetricsCommon::FileUtils::Ptr m_fileUtils; |
2047 | + |
2048 | + QFileSystemWatcher m_watcher; |
2049 | + |
2050 | + QMap<QString, DirectoryWatcher::Ptr> m_directories; |
2051 | +}; |
2052 | + |
2053 | +} |
2054 | + |
2055 | +#endif /* USERMETRICSOUTPUT_DIRECTORYWATCHER_H_ */ |
2056 | |
2057 | === added file 'src/libusermetricsoutput/InfographicList.cpp' |
2058 | --- src/libusermetricsoutput/InfographicList.cpp 1970-01-01 00:00:00 +0000 |
2059 | +++ src/libusermetricsoutput/InfographicList.cpp 2014-04-03 13:02:15 +0000 |
2060 | @@ -0,0 +1,32 @@ |
2061 | +/* |
2062 | + * Copyright (C) 2014 Canonical, Ltd. |
2063 | + * |
2064 | + * This library is free software; you can redistribute it and/or modify it under |
2065 | + * the terms of version 3 of the GNU Lesser General Public License as published |
2066 | + * by the Free Software Foundation. |
2067 | + * |
2068 | + * This library is distributed in the hope that it will be useful, but WITHOUT |
2069 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
2070 | + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
2071 | + * details. |
2072 | + * |
2073 | + * You should have received a copy of the GNU Lesser General Public License |
2074 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2075 | + * |
2076 | + * Author: Pete Woods <pete.woods@canonical.com> |
2077 | + */ |
2078 | + |
2079 | +#include <libusermetricsoutput/InfographicListImpl.h> |
2080 | + |
2081 | +using namespace UserMetricsOutput; |
2082 | + |
2083 | +InfographicList::InfographicList(QObject *parent) : |
2084 | + QStringListModel(parent) { |
2085 | +} |
2086 | + |
2087 | +InfographicList::~InfographicList() { |
2088 | +} |
2089 | + |
2090 | +InfographicList * InfographicList::getInstance(const QString &path) { |
2091 | + return new InfographicListImpl(path); |
2092 | +} |
2093 | |
2094 | === added file 'src/libusermetricsoutput/InfographicList.h' |
2095 | --- src/libusermetricsoutput/InfographicList.h 1970-01-01 00:00:00 +0000 |
2096 | +++ src/libusermetricsoutput/InfographicList.h 2014-04-03 13:02:15 +0000 |
2097 | @@ -0,0 +1,106 @@ |
2098 | +/* |
2099 | + * Copyright (C) 2014 Canonical, Ltd. |
2100 | + * |
2101 | + * This library is free software; you can redistribute it and/or modify it under |
2102 | + * the terms of version 3 of the GNU Lesser General Public License as published |
2103 | + * by the Free Software Foundation. |
2104 | + * |
2105 | + * This library is distributed in the hope that it will be useful, but WITHOUT |
2106 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
2107 | + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
2108 | + * details. |
2109 | + * |
2110 | + * You should have received a copy of the GNU Lesser General Public License |
2111 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2112 | + * |
2113 | + * Author: Pete Woods <pete.woods@canonical.com> |
2114 | + */ |
2115 | + |
2116 | +#ifndef USERMETRICSOUTPUT_INFOGRAPHICLIST_H_ |
2117 | +#define USERMETRICSOUTPUT_INFOGRAPHICLIST_H_ |
2118 | + |
2119 | +#include <QtCore/QStringList> |
2120 | +#include <QtCore/QStringListModel> |
2121 | + |
2122 | +/** |
2123 | + * @{ |
2124 | + **/ |
2125 | + |
2126 | +/** |
2127 | + * @brief The user metrics output library namespace |
2128 | + **/ |
2129 | +namespace UserMetricsOutput { |
2130 | + |
2131 | +/** |
2132 | + * @brief Presentation API for infographics. |
2133 | + * |
2134 | + * This class essentially provides a list of paths to |
2135 | + * infographic image files. |
2136 | + * |
2137 | + * Given a user ID, this class watches the corresponding |
2138 | + * directory in /var/lib/usermetrics/{userid}/ for changes |
2139 | + * to SVG files. |
2140 | + * |
2141 | + **/ |
2142 | +class Q_DECL_EXPORT InfographicList: public QStringListModel { |
2143 | +Q_OBJECT |
2144 | + |
2145 | +/** |
2146 | + * @brief The current user ID selected. |
2147 | + */ |
2148 | +Q_PROPERTY(unsigned int uid READ uid WRITE setUid NOTIFY uidChanged FINAL) |
2149 | + |
2150 | +public: |
2151 | + /** |
2152 | + * @brief Get a new instance of InfographicList. |
2153 | + */ |
2154 | + static InfographicList *getInstance( |
2155 | + const QString &path = QString("/var/lib/usermetrics/")); |
2156 | + |
2157 | + /** |
2158 | + * @brief Destructor. |
2159 | + */ |
2160 | + virtual ~InfographicList(); |
2161 | + |
2162 | + /** |
2163 | + * @brief The current user ID selected. |
2164 | + */ |
2165 | + virtual unsigned int uid() const = 0; |
2166 | + |
2167 | + |
2168 | +Q_SIGNALS: |
2169 | + /** |
2170 | + * @brief The user ID has changed |
2171 | + * |
2172 | + * @param uid |
2173 | + */ |
2174 | + void uidChanged(unsigned int uid); |
2175 | + |
2176 | +public Q_SLOTS: |
2177 | + /** |
2178 | + * @brief Change the current user ID. |
2179 | + * |
2180 | + * @param uid |
2181 | + * |
2182 | + * The data source will change to the first one available |
2183 | + * for the given user ID. |
2184 | + */ |
2185 | + virtual void setUid(unsigned int uid) = 0; |
2186 | + |
2187 | +protected: |
2188 | + /** |
2189 | + * @brief Unusable constructor - this class is pure-virtual. |
2190 | + * |
2191 | + * @param parent |
2192 | + */ |
2193 | + explicit InfographicList(QObject *parent = 0); |
2194 | + |
2195 | + Q_DISABLE_COPY(InfographicList) |
2196 | + |
2197 | +}; |
2198 | + |
2199 | +} |
2200 | + |
2201 | +/*@}*/ |
2202 | + |
2203 | +#endif // USERMETRICSOUTPUT_INFOGRAPHICLIST_H_ |
2204 | |
2205 | === added file 'src/libusermetricsoutput/InfographicListImpl.cpp' |
2206 | --- src/libusermetricsoutput/InfographicListImpl.cpp 1970-01-01 00:00:00 +0000 |
2207 | +++ src/libusermetricsoutput/InfographicListImpl.cpp 2014-04-03 13:02:15 +0000 |
2208 | @@ -0,0 +1,139 @@ |
2209 | +/* |
2210 | + * Copyright (C) 2014 Canonical, Ltd. |
2211 | + * |
2212 | + * This library is free software; you can redistribute it and/or modify it under |
2213 | + * the terms of version 3 of the GNU Lesser General Public License as published |
2214 | + * by the Free Software Foundation. |
2215 | + * |
2216 | + * This library is distributed in the hope that it will be useful, but WITHOUT |
2217 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
2218 | + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
2219 | + * details. |
2220 | + * |
2221 | + * You should have received a copy of the GNU Lesser General Public License |
2222 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2223 | + * |
2224 | + * Author: Pete Woods <pete.woods@canonical.com> |
2225 | + */ |
2226 | + |
2227 | +#include <libusermetricscommon/FileUtils.h> |
2228 | +#include <libusermetricsoutput/InfographicListImpl.h> |
2229 | + |
2230 | +#include <QtCore/QDebug> |
2231 | +#include <algorithm> |
2232 | + |
2233 | +using namespace UserMetricsCommon; |
2234 | +using namespace UserMetricsOutput; |
2235 | + |
2236 | +InfographicListImpl::InfographicListImpl(const QString &path, QObject *parent) : |
2237 | + InfographicList(parent), m_path(path), m_uid(0) { |
2238 | + |
2239 | + connect(&m_timer, &QTimer::timeout, this, &InfographicListImpl::timeout); |
2240 | + connect(&m_filesystemWatcher, &QFileSystemWatcher::directoryChanged, this, |
2241 | + &InfographicListImpl::internalDirectoryChanged); |
2242 | + |
2243 | + m_timer.setSingleShot(true); |
2244 | + m_filesystemWatcher.addPath(path); |
2245 | + m_workerThread.start(); |
2246 | +} |
2247 | + |
2248 | +InfographicListImpl::~InfographicListImpl() { |
2249 | + m_workerThread.quit(); |
2250 | + m_workerThread.wait(); |
2251 | +} |
2252 | + |
2253 | +unsigned int InfographicListImpl::uid() const { |
2254 | + return m_uid; |
2255 | +} |
2256 | + |
2257 | +void InfographicListImpl::newDirectoryWatcher() { |
2258 | + m_directoryWatcher.reset( |
2259 | + new DirectoryWatcher(m_userDir, 1, FileUtils::Ptr(new FileUtils())), |
2260 | + &QObject::deleteLater); |
2261 | + m_directoryWatcher->moveToThread(&m_workerThread); |
2262 | + connect(m_directoryWatcher.data(), &DirectoryWatcher::directoryChanged, |
2263 | + this, &InfographicListImpl::directoryContentsChanged); |
2264 | + connect(m_directoryWatcher.data(), &DirectoryWatcher::directoryRemoved, |
2265 | + this, &InfographicListImpl::directoryRemoved); |
2266 | + QTimer::singleShot(0, m_directoryWatcher.data(), SLOT(start())); |
2267 | +} |
2268 | + |
2269 | +void InfographicListImpl::setUid(unsigned int uid) { |
2270 | + if (uid == m_uid) { |
2271 | + return; |
2272 | + } |
2273 | + |
2274 | + m_uid = uid; |
2275 | + m_userDir = m_path.filePath(QString::number(m_uid)); |
2276 | + |
2277 | + if (m_userDir.exists()) { |
2278 | + newDirectoryWatcher(); |
2279 | + } |
2280 | +} |
2281 | + |
2282 | +void InfographicListImpl::internalDirectoryChanged() { |
2283 | + if (m_uid == 0) { |
2284 | + return; |
2285 | + } |
2286 | + |
2287 | + bool exists(m_userDir.exists()); |
2288 | + |
2289 | + if (m_directoryWatcher) { |
2290 | + if (!exists) { |
2291 | + m_directoryWatcher.reset(); |
2292 | + } |
2293 | + } else { |
2294 | + newDirectoryWatcher(); |
2295 | + } |
2296 | +} |
2297 | + |
2298 | +void InfographicListImpl::directoryContentsChanged(const QString &directory, |
2299 | + const QStringList &files) { |
2300 | + m_files.remove(directory); |
2301 | + for (const QString &file : files) { |
2302 | + m_files.insert(directory, file); |
2303 | + } |
2304 | + m_timer.start(100); |
2305 | +} |
2306 | + |
2307 | +void InfographicListImpl::directoryRemoved(const QString &name) { |
2308 | + m_files.remove(name); |
2309 | + m_timer.start(100); |
2310 | +} |
2311 | + |
2312 | +void InfographicListImpl::timeout() { |
2313 | + if (!m_directoryWatcher) { |
2314 | + return; |
2315 | + } |
2316 | + |
2317 | + int existingRows(rowCount()); |
2318 | + int newRows(m_files.count()); |
2319 | + |
2320 | + // Special case the initial insert |
2321 | + if (existingRows == 0 && newRows > 0) { |
2322 | + setStringList(m_files.values()); |
2323 | + return; |
2324 | + } |
2325 | + |
2326 | + if (newRows > existingRows) { |
2327 | + // insert new rows |
2328 | + insertRows(existingRows, newRows - existingRows); |
2329 | + } else if (newRows < existingRows) { |
2330 | + // remove extra rows |
2331 | + removeRows(newRows, existingRows - newRows); |
2332 | + } |
2333 | + |
2334 | + int row(0); |
2335 | + QMapIterator<QString, QString> it(m_files); |
2336 | + while (it.hasNext()) { |
2337 | + it.next(); |
2338 | + const QString &file(it.value()); |
2339 | + |
2340 | + QString existing(data(index(row, 0), Qt::DisplayRole).toString()); |
2341 | + if (existing != file) { |
2342 | + setData(index(row, 0), file); |
2343 | + } |
2344 | + ++row; |
2345 | + } |
2346 | +} |
2347 | + |
2348 | |
2349 | === added file 'src/libusermetricsoutput/InfographicListImpl.h' |
2350 | --- src/libusermetricsoutput/InfographicListImpl.h 1970-01-01 00:00:00 +0000 |
2351 | +++ src/libusermetricsoutput/InfographicListImpl.h 2014-04-03 13:02:15 +0000 |
2352 | @@ -0,0 +1,79 @@ |
2353 | +/* |
2354 | + * Copyright (C) 2014 Canonical, Ltd. |
2355 | + * |
2356 | + * This library is free software; you can redistribute it and/or modify it under |
2357 | + * the terms of version 3 of the GNU Lesser General Public License as published |
2358 | + * by the Free Software Foundation. |
2359 | + * |
2360 | + * This library is distributed in the hope that it will be useful, but WITHOUT |
2361 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
2362 | + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
2363 | + * details. |
2364 | + * |
2365 | + * You should have received a copy of the GNU Lesser General Public License |
2366 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2367 | + * |
2368 | + * Author: Pete Woods <pete.woods@canonical.com> |
2369 | + */ |
2370 | + |
2371 | +#ifndef USERMETRICSOUTPUT_INFOGRAPHICLISTIMPL_H_ |
2372 | +#define USERMETRICSOUTPUT_INFOGRAPHICLISTIMPL_H_ |
2373 | + |
2374 | +#include <libusermetricsoutput/DirectoryWatcher.h> |
2375 | +#include <libusermetricsoutput/InfographicList.h> |
2376 | + |
2377 | +#include <QtCore/QDir> |
2378 | +#include <QtCore/QString> |
2379 | +#include <QtCore/QFileSystemWatcher> |
2380 | +#include <QtCore/QMultiMap> |
2381 | +#include <QtCore/QThread> |
2382 | +#include <QtCore/QTimer> |
2383 | +#include <QtCore/QScopedPointer> |
2384 | + |
2385 | +namespace UserMetricsOutput { |
2386 | + |
2387 | +class InfographicListImpl: public InfographicList { |
2388 | +Q_OBJECT |
2389 | + |
2390 | +public: |
2391 | + InfographicListImpl(const QString &path, QObject *parent = 0); |
2392 | + |
2393 | + virtual ~InfographicListImpl(); |
2394 | + |
2395 | + unsigned int uid() const override; |
2396 | + |
2397 | + void setUid(unsigned int uid) override; |
2398 | + |
2399 | +protected Q_SLOTS: |
2400 | + void internalDirectoryChanged(); |
2401 | + |
2402 | + void directoryContentsChanged(const QString &directory, |
2403 | + const QStringList &files); |
2404 | + |
2405 | + void directoryRemoved(const QString &directory); |
2406 | + |
2407 | + void timeout(); |
2408 | + |
2409 | +protected: |
2410 | + void newDirectoryWatcher(); |
2411 | + |
2412 | + QThread m_workerThread; |
2413 | + |
2414 | + QTimer m_timer; |
2415 | + |
2416 | + QDir m_path; |
2417 | + |
2418 | + QDir m_userDir; |
2419 | + |
2420 | + unsigned int m_uid; |
2421 | + |
2422 | + QFileSystemWatcher m_filesystemWatcher; |
2423 | + |
2424 | + DirectoryWatcher::Ptr m_directoryWatcher; |
2425 | + |
2426 | + QMultiMap<QString, QString> m_files; |
2427 | +}; |
2428 | + |
2429 | +} |
2430 | + |
2431 | +#endif /* USERMETRICSOUTPUT_INFOGRAPHICLISTIMPL_H_ */ |
2432 | |
2433 | === modified file 'src/usermetricsservice/CMakeLists.txt' |
2434 | --- src/usermetricsservice/CMakeLists.txt 2014-01-03 11:40:22 +0000 |
2435 | +++ src/usermetricsservice/CMakeLists.txt 2014-04-03 13:02:15 +0000 |
2436 | @@ -1,17 +1,34 @@ |
2437 | |
2438 | -#set(USERMETRICSSERVICE_SOURCES |
2439 | -#) |
2440 | - |
2441 | -#add_library( |
2442 | -# usermetricsservice |
2443 | -# STATIC |
2444 | -# ${USERMETRICSSERVICE_SOURCES} |
2445 | -#) |
2446 | - |
2447 | -#target_link_libraries( |
2448 | -# usermetricsservice |
2449 | -# ${APPARMOR_LIBRARIES} |
2450 | -#) |
2451 | +set(USERMETRICSSERVICE_SOURCES |
2452 | + Executor.cpp |
2453 | + Factory.cpp |
2454 | + Infographic.cpp |
2455 | + InfographicImpl.cpp |
2456 | + QProcessExecutor.cpp |
2457 | + ResultTransport.cpp |
2458 | + ResultTransportImpl.cpp |
2459 | + SourceDirectory.cpp |
2460 | + SourceDirectoryImpl.cpp |
2461 | + Service.cpp |
2462 | + ServiceImpl.cpp |
2463 | +) |
2464 | + |
2465 | +add_library( |
2466 | + usermetricsservice |
2467 | + STATIC |
2468 | + ${USERMETRICSSERVICE_SOURCES} |
2469 | +) |
2470 | + |
2471 | +target_link_libraries( |
2472 | + usermetricsservice |
2473 | + usermetricscommon |
2474 | +) |
2475 | + |
2476 | +qt5_use_modules( |
2477 | + usermetricsservice |
2478 | + Core |
2479 | + DBus |
2480 | +) |
2481 | |
2482 | ############################ |
2483 | # Service executable |
2484 | @@ -28,16 +45,42 @@ |
2485 | OUTPUT_NAME "usermetricsservice" |
2486 | ) |
2487 | |
2488 | -#target_link_libraries( |
2489 | -# usermetricsservice-bin |
2490 | -# usermetricsservice |
2491 | -#) |
2492 | +target_link_libraries( |
2493 | + usermetricsservice-bin |
2494 | + usermetricsservice |
2495 | +) |
2496 | + |
2497 | +qt5_use_modules( |
2498 | + usermetricsservice-bin |
2499 | + Core |
2500 | +) |
2501 | + |
2502 | +######################### |
2503 | +# Sandbox executable |
2504 | +######################### |
2505 | + |
2506 | +add_executable( |
2507 | + aa-exec |
2508 | + aa-exec.cpp |
2509 | +) |
2510 | + |
2511 | +target_link_libraries( |
2512 | + aa-exec |
2513 | + ${APPARMOR_LDFLAGS} |
2514 | +) |
2515 | + |
2516 | +add_definitions( |
2517 | + -DAA_EXEC_PATH="${CMAKE_INSTALL_FULL_LIBEXECDIR}/libusermetrics/aa-exec" |
2518 | +) |
2519 | |
2520 | ######################### |
2521 | # Installation |
2522 | ######################### |
2523 | |
2524 | install( |
2525 | - TARGETS usermetricsservice-bin |
2526 | - RUNTIME DESTINATION "${CMAKE_INSTALL_FULL_LIBEXECDIR}/libusermetrics" |
2527 | + TARGETS |
2528 | + usermetricsservice-bin |
2529 | + aa-exec |
2530 | + RUNTIME DESTINATION |
2531 | + "${CMAKE_INSTALL_FULL_LIBEXECDIR}/libusermetrics" |
2532 | ) |
2533 | |
2534 | === removed file 'src/usermetricsservice/DBusUserData.cpp' |
2535 | --- src/usermetricsservice/DBusUserData.cpp 2014-01-20 10:33:36 +0000 |
2536 | +++ src/usermetricsservice/DBusUserData.cpp 1970-01-01 00:00:00 +0000 |
2537 | @@ -1,186 +0,0 @@ |
2538 | -/* |
2539 | - * Copyright (C) 2013 Canonical, Ltd. |
2540 | - * |
2541 | - * This program is free software; you can redistribute it and/or modify |
2542 | - * it under the terms of the GNU General Public License as published by |
2543 | - * the Free Software Foundation; version 3. |
2544 | - * |
2545 | - * This program is distributed in the hope that it will be useful, |
2546 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2547 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2548 | - * GNU General Public License for more details. |
2549 | - * |
2550 | - * You should have received a copy of the GNU General Public License |
2551 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2552 | - * |
2553 | - * Author: Pete Woods <pete.woods@canonical.com> |
2554 | - */ |
2555 | - |
2556 | -#include <stdexcept> |
2557 | - |
2558 | -#include <usermetricsservice/Authentication.h> |
2559 | -#include <usermetricsservice/DBusUserMetrics.h> |
2560 | -#include <usermetricsservice/DBusUserData.h> |
2561 | -#include <usermetricsservice/DBusDataSet.h> |
2562 | -#include <usermetricsservice/DBusDataSource.h> |
2563 | -#include <usermetricsservice/UserDataAdaptor.h> |
2564 | -#include <usermetricsservice/database/DataSet.h> |
2565 | -#include <usermetricsservice/database/DataSource.h> |
2566 | -#include <usermetricsservice/database/UserData.h> |
2567 | -#include <libusermetricscommon/DateFactory.h> |
2568 | -#include <libusermetricscommon/DBusPaths.h> |
2569 | -#include <libusermetricscommon/Localisation.h> |
2570 | - |
2571 | -#include <QDjangoQuerySet.h> |
2572 | - |
2573 | -using namespace std; |
2574 | -using namespace UserMetricsCommon; |
2575 | -using namespace UserMetricsService; |
2576 | - |
2577 | -DBusUserData::DBusUserData(int id, const QString &username, |
2578 | - DBusUserMetrics &userMetrics, QDBusConnection &dbusConnection, |
2579 | - QSharedPointer<DateFactory> dateFactory, |
2580 | - QSharedPointer<Authentication> authentication, QObject *parent) : |
2581 | - QObject(parent), m_dbusConnection(dbusConnection), m_adaptor( |
2582 | - new UserDataAdaptor(this)), m_dateFactory(dateFactory), m_authentication( |
2583 | - authentication), m_userMetrics(userMetrics), m_id(id), m_path( |
2584 | - DBusPaths::userData(m_id)), m_username(username) { |
2585 | - |
2586 | - // DBus setup |
2587 | - if (!m_dbusConnection.registerObject(m_path, this)) { |
2588 | - throw logic_error(_("Could not register user data object with DBus")); |
2589 | - } |
2590 | - |
2591 | -// Database setup |
2592 | - syncDatabase(); |
2593 | -} |
2594 | - |
2595 | -DBusUserData::~DBusUserData() { |
2596 | - QDBusConnection connection(QDBusConnection::sessionBus()); |
2597 | - connection.unregisterObject(m_path); |
2598 | -} |
2599 | - |
2600 | -QString DBusUserData::path() const { |
2601 | - return m_path; |
2602 | -} |
2603 | - |
2604 | -QString DBusUserData::username() const { |
2605 | - return m_username; |
2606 | -} |
2607 | - |
2608 | -QList<QDBusObjectPath> DBusUserData::dataSets() const { |
2609 | - QList<QDBusObjectPath> dataSets; |
2610 | - for (DBusDataSetPtr dataSet : m_dataSets.values()) { |
2611 | - dataSets << QDBusObjectPath(dataSet->path()); |
2612 | - } |
2613 | - return dataSets; |
2614 | -} |
2615 | - |
2616 | -QDBusObjectPath DBusUserData::createDataSet(const QString &dataSourceName) { |
2617 | - if (!DataSource::exists(dataSourceName)) { |
2618 | - qWarning() << _("Unknown data source") << ": [" << dataSourceName |
2619 | - << "]"; |
2620 | - return QDBusObjectPath(); |
2621 | - } |
2622 | - |
2623 | - QString dbusUsername(m_authentication->getUsername(*this)); |
2624 | - if (!dbusUsername.isEmpty() && !m_username.isEmpty() |
2625 | - && dbusUsername != m_username) { |
2626 | - m_authentication->sendErrorReply(*this, QDBusError::AccessDenied, |
2627 | - _("Attempt to create data set owned by another user")); |
2628 | - return QDBusObjectPath(); |
2629 | - } |
2630 | - |
2631 | - QString confinementContext(m_authentication->getConfinementContext(*this)); |
2632 | - DataSource dataSource; |
2633 | - DataSource::findByNameAndSecret(dataSourceName, confinementContext, |
2634 | - &dataSource); |
2635 | - if (!dataSource.isValid()) { |
2636 | - m_authentication->sendErrorReply(*this, QDBusError::InternalError, |
2637 | - _("Could not locate user data")); |
2638 | - return QDBusObjectPath(); |
2639 | - } |
2640 | - if (dataSource.secret() != "unconfined" |
2641 | - && dataSource.secret() != confinementContext) { |
2642 | - m_authentication->sendErrorReply(*this, QDBusError::AccessDenied, |
2643 | - _("Attempt to create data set owned by another application")); |
2644 | - return QDBusObjectPath(); |
2645 | - } |
2646 | - |
2647 | - QDjangoQuerySet<DataSet> dataSets; |
2648 | - QDjangoQuerySet<DataSet> query = dataSets.filter( |
2649 | - QDjangoWhere("userData_id", QDjangoWhere::Equals, m_id)).filter( |
2650 | - QDjangoWhere("dataSource__name", QDjangoWhere::Equals, |
2651 | - dataSourceName)); |
2652 | - |
2653 | - if (query.size() == -1) { |
2654 | - throw logic_error(_("Data set query failed")); |
2655 | - } |
2656 | - |
2657 | - DataSet dataSet; |
2658 | - |
2659 | - if (query.size() == 0) { |
2660 | - UserData userData; |
2661 | - UserData::findById(m_id, &userData); |
2662 | - dataSet.setUserData(&userData); |
2663 | - |
2664 | - dataSet.setDataSource(&dataSource); |
2665 | - |
2666 | - if (!dataSet.save()) { |
2667 | - throw logic_error(_("Could not save data set")); |
2668 | - } |
2669 | - |
2670 | - syncDatabase(); |
2671 | - } else { |
2672 | - query.at(0, &dataSet); |
2673 | - } |
2674 | - |
2675 | - DBusDataSetPtr dataSetPtr(m_dataSets.value(dataSet.id())); |
2676 | - if (dataSetPtr.isNull()) { |
2677 | - throw logic_error(_("New data set could not be found")); |
2678 | - } |
2679 | - return QDBusObjectPath(dataSetPtr->path()); |
2680 | -} |
2681 | - |
2682 | -void DBusUserData::syncDatabase() { |
2683 | - QSet<int> dataSetIds; |
2684 | - QDjangoQuerySet<DataSet> dataSets; |
2685 | - QDjangoQuerySet<DataSet> query( |
2686 | - dataSets.filter( |
2687 | - QDjangoWhere("userData_id", QDjangoWhere::Equals, m_id))); |
2688 | - for (const DataSet &dataSet : query.selectRelated()) { |
2689 | - const int id(dataSet.id()); |
2690 | - dataSetIds << id; |
2691 | - // if we don't have a local cache |
2692 | - if (!m_dataSets.contains(id)) { |
2693 | - DBusDataSourcePtr dbusDataSource( |
2694 | - m_userMetrics.dataSource(dataSet.dataSource()->name(), |
2695 | - dataSet.dataSource()->secret())); |
2696 | - DBusDataSetPtr dbusDataSet( |
2697 | - new DBusDataSet(id, dbusDataSource->path(), |
2698 | - m_dbusConnection, m_dateFactory, m_authentication)); |
2699 | - m_dataSets.insert(id, dbusDataSet); |
2700 | - m_adaptor->dataSetAdded(QDBusObjectPath(dbusDataSet->dataSource()), |
2701 | - QDBusObjectPath(dbusDataSet->path())); |
2702 | - } |
2703 | - } |
2704 | - // remove any cached references to deleted data sets |
2705 | - QSet<int> cachedDataSetIds(QSet<int>::fromList(m_dataSets.keys())); |
2706 | - QSet<int> &toRemove(cachedDataSetIds.subtract(dataSetIds)); |
2707 | - for (int id : toRemove) { |
2708 | - DBusDataSetPtr dataSet = m_dataSets.take(id); |
2709 | - m_adaptor->dataSetRemoved(QDBusObjectPath(dataSet->dataSource()), |
2710 | - QDBusObjectPath(dataSet->path())); |
2711 | - } |
2712 | -} |
2713 | - |
2714 | -DBusDataSetPtr DBusUserData::dataSet(const QString &dataSource) const { |
2715 | - QDjangoQuerySet<DataSet> dataSets; |
2716 | - QScopedPointer<DataSet> dataSet( |
2717 | - dataSets.filter( |
2718 | - QDjangoWhere("userData_id", QDjangoWhere::Equals, m_id)).get( |
2719 | - QDjangoWhere("dataSource__name", QDjangoWhere::Equals, |
2720 | - dataSource))); |
2721 | - |
2722 | - return m_dataSets.value(dataSet->id()); |
2723 | -} |
2724 | |
2725 | === added file 'src/usermetricsservice/Executor.cpp' |
2726 | --- src/usermetricsservice/Executor.cpp 1970-01-01 00:00:00 +0000 |
2727 | +++ src/usermetricsservice/Executor.cpp 2014-04-03 13:02:15 +0000 |
2728 | @@ -0,0 +1,27 @@ |
2729 | +/* |
2730 | + * Copyright (C) 2014 Canonical, Ltd. |
2731 | + * |
2732 | + * This program is free software; you can redistribute it and/or modify |
2733 | + * it under the terms of the GNU General Public License as published by |
2734 | + * the Free Software Foundation; version 3. |
2735 | + * |
2736 | + * This program is distributed in the hope that it will be useful, |
2737 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2738 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2739 | + * GNU General Public License for more details. |
2740 | + * |
2741 | + * You should have received a copy of the GNU General Public License |
2742 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2743 | + * |
2744 | + * Author: Pete Woods <pete.woods@canonical.com> |
2745 | + */ |
2746 | + |
2747 | +#include <usermetricsservice/Executor.h> |
2748 | + |
2749 | +using namespace UserMetricsService; |
2750 | + |
2751 | +Executor::Executor() { |
2752 | +} |
2753 | + |
2754 | +Executor::~Executor() { |
2755 | +} |
2756 | |
2757 | === added file 'src/usermetricsservice/Executor.h' |
2758 | --- src/usermetricsservice/Executor.h 1970-01-01 00:00:00 +0000 |
2759 | +++ src/usermetricsservice/Executor.h 2014-04-03 13:02:15 +0000 |
2760 | @@ -0,0 +1,42 @@ |
2761 | +/* |
2762 | + * Copyright (C) 2014 Canonical, Ltd. |
2763 | + * |
2764 | + * This program is free software; you can redistribute it and/or modify |
2765 | + * it under the terms of the GNU General Public License as published by |
2766 | + * the Free Software Foundation; version 3. |
2767 | + * |
2768 | + * This program is distributed in the hope that it will be useful, |
2769 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2770 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2771 | + * GNU General Public License for more details. |
2772 | + * |
2773 | + * You should have received a copy of the GNU General Public License |
2774 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2775 | + * |
2776 | + * Author: Pete Woods <pete.woods@canonical.com> |
2777 | + */ |
2778 | + |
2779 | +#ifndef USERMETRICSSERVICE_EXECUTOR_H_ |
2780 | +#define USERMETRICSSERVICE_EXECUTOR_H_ |
2781 | + |
2782 | +#include <QByteArray> |
2783 | +#include <QSharedPointer> |
2784 | +#include <QStringList> |
2785 | + |
2786 | +namespace UserMetricsService { |
2787 | + |
2788 | +class Executor { |
2789 | +public: |
2790 | + typedef QSharedPointer<Executor> Ptr; |
2791 | + |
2792 | + Executor(); |
2793 | + |
2794 | + virtual ~Executor(); |
2795 | + |
2796 | + virtual QByteArray execute(const QString &program, |
2797 | + const QStringList &arguments) = 0; |
2798 | +}; |
2799 | + |
2800 | +} |
2801 | + |
2802 | +#endif /* USERMETRICSSERVICE_EXECUTOR_H_ */ |
2803 | |
2804 | === added file 'src/usermetricsservice/Factory.cpp' |
2805 | --- src/usermetricsservice/Factory.cpp 1970-01-01 00:00:00 +0000 |
2806 | +++ src/usermetricsservice/Factory.cpp 2014-04-03 13:02:15 +0000 |
2807 | @@ -0,0 +1,90 @@ |
2808 | +/* |
2809 | + * Copyright (C) 2014 Canonical, Ltd. |
2810 | + * |
2811 | + * This program is free software; you can redistribute it and/or modify |
2812 | + * it under the terms of the GNU General Public License as published by |
2813 | + * the Free Software Foundation; version 3. |
2814 | + * |
2815 | + * This program is distributed in the hope that it will be useful, |
2816 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2817 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2818 | + * GNU General Public License for more details. |
2819 | + * |
2820 | + * You should have received a copy of the GNU General Public License |
2821 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2822 | + * |
2823 | + * Author: Pete Woods <pete.woods@canonical.com> |
2824 | + */ |
2825 | + |
2826 | +#include <libusermetricscommon/DBusPaths.h> |
2827 | +#include <usermetricsservice/Factory.h> |
2828 | +#include <usermetricsservice/InfographicImpl.h> |
2829 | +#include <usermetricsservice/QProcessExecutor.h> |
2830 | +#include <usermetricsservice/ResultTransportImpl.h> |
2831 | +#include <usermetricsservice/SourceDirectoryImpl.h> |
2832 | +#include <usermetricsservice/ServiceImpl.h> |
2833 | + |
2834 | +using namespace UserMetricsCommon; |
2835 | +using namespace UserMetricsService; |
2836 | + |
2837 | +Factory::Factory() { |
2838 | +} |
2839 | + |
2840 | +Factory::~Factory() { |
2841 | +} |
2842 | + |
2843 | +Service::Ptr Factory::singletonService() { |
2844 | + if (!m_service) { |
2845 | + m_service.reset( |
2846 | + new ServiceImpl(QDir::home().filePath(".cache"), |
2847 | + QDir("/usr/share/libusermetrics/infographics"), |
2848 | + singletonFileUtils(), singletonResultTransport(), |
2849 | + *this)); |
2850 | + } |
2851 | + return m_service; |
2852 | +} |
2853 | + |
2854 | +FileUtils::Ptr Factory::singletonFileUtils() { |
2855 | + if (!m_fileUtils) { |
2856 | + m_fileUtils.reset(new FileUtils()); |
2857 | + } |
2858 | + return m_fileUtils; |
2859 | +} |
2860 | + |
2861 | +Executor::Ptr Factory::singletonExecutor() { |
2862 | + if (!m_executor) { |
2863 | + m_executor.reset(new QProcessExecutor(QDir::home().filePath(".cache"), |
2864 | + AA_EXEC_PATH)); |
2865 | + } |
2866 | + return m_executor; |
2867 | +} |
2868 | + |
2869 | +QSharedPointer<ComCanonicalInfographicsInterface> Factory::singletonInfographicService() { |
2870 | + if (!m_infographicService) { |
2871 | + m_infographicService.reset( |
2872 | + new ComCanonicalInfographicsInterface( |
2873 | + DBusPaths::INFOGRAPHIC_DBUS_NAME, |
2874 | + DBusPaths::INFOGRAPHIC_DBUS_PATH, |
2875 | + QDBusConnection::systemBus())); |
2876 | + } |
2877 | + return m_infographicService; |
2878 | +} |
2879 | + |
2880 | +ResultTransport::Ptr Factory::singletonResultTransport() { |
2881 | + if (!m_resultTransport) { |
2882 | + m_resultTransport.reset( |
2883 | + new ResultTransportImpl(singletonInfographicService())); |
2884 | + } |
2885 | + return m_resultTransport; |
2886 | +} |
2887 | + |
2888 | +Infographic::Ptr Factory::newInfographic(const QFile &path) { |
2889 | + return Infographic::Ptr( |
2890 | + new InfographicImpl(path, singletonExecutor(), |
2891 | + singletonResultTransport())); |
2892 | +} |
2893 | + |
2894 | +SourceDirectory::Ptr Factory::newSourceDirectory(const QDir &path) { |
2895 | + return SourceDirectory::Ptr( |
2896 | + new SourceDirectoryImpl(path, singletonFileUtils())); |
2897 | +} |
2898 | |
2899 | === added file 'src/usermetricsservice/Factory.h' |
2900 | --- src/usermetricsservice/Factory.h 1970-01-01 00:00:00 +0000 |
2901 | +++ src/usermetricsservice/Factory.h 2014-04-03 13:02:15 +0000 |
2902 | @@ -0,0 +1,69 @@ |
2903 | +/* |
2904 | + * Copyright (C) 2014 Canonical, Ltd. |
2905 | + * |
2906 | + * This program is free software; you can redistribute it and/or modify |
2907 | + * it under the terms of the GNU General Public License as published by |
2908 | + * the Free Software Foundation; version 3. |
2909 | + * |
2910 | + * This program is distributed in the hope that it will be useful, |
2911 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2912 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2913 | + * GNU General Public License for more details. |
2914 | + * |
2915 | + * You should have received a copy of the GNU General Public License |
2916 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2917 | + * |
2918 | + * Author: Pete Woods <pete.woods@canonical.com> |
2919 | + */ |
2920 | + |
2921 | +#ifndef USERMETRICSSERVICE_FACTORY_H_ |
2922 | +#define USERMETRICSSERVICE_FACTORY_H_ |
2923 | + |
2924 | +#include <libusermetricscommon/FileUtils.h> |
2925 | +#include <libusermetricscommon/InfographicsInterface.h> |
2926 | +#include <usermetricsservice/Executor.h> |
2927 | +#include <usermetricsservice/Infographic.h> |
2928 | +#include <usermetricsservice/ResultTransport.h> |
2929 | +#include <usermetricsservice/Service.h> |
2930 | +#include <usermetricsservice/SourceDirectory.h> |
2931 | + |
2932 | +#include <QFile> |
2933 | +#include <QDir> |
2934 | + |
2935 | +namespace UserMetricsService { |
2936 | + |
2937 | +class Factory { |
2938 | +public: |
2939 | + Factory(); |
2940 | + |
2941 | + virtual ~Factory(); |
2942 | + |
2943 | + virtual Service::Ptr singletonService(); |
2944 | + |
2945 | + virtual UserMetricsCommon::FileUtils::Ptr singletonFileUtils(); |
2946 | + |
2947 | + virtual Executor::Ptr singletonExecutor(); |
2948 | + |
2949 | + virtual QSharedPointer<ComCanonicalInfographicsInterface> singletonInfographicService(); |
2950 | + |
2951 | + virtual ResultTransport::Ptr singletonResultTransport(); |
2952 | + |
2953 | + virtual Infographic::Ptr newInfographic(const QFile &path); |
2954 | + |
2955 | + virtual SourceDirectory::Ptr newSourceDirectory(const QDir &path); |
2956 | + |
2957 | +protected: |
2958 | + Service::Ptr m_service; |
2959 | + |
2960 | + UserMetricsCommon::FileUtils::Ptr m_fileUtils; |
2961 | + |
2962 | + Executor::Ptr m_executor; |
2963 | + |
2964 | + QSharedPointer<ComCanonicalInfographicsInterface> m_infographicService; |
2965 | + |
2966 | + ResultTransport::Ptr m_resultTransport; |
2967 | +}; |
2968 | + |
2969 | +} |
2970 | + |
2971 | +#endif /* USERMETRICSSERVICE_FACTORY_H_ */ |
2972 | |
2973 | === added file 'src/usermetricsservice/Infographic.cpp' |
2974 | --- src/usermetricsservice/Infographic.cpp 1970-01-01 00:00:00 +0000 |
2975 | +++ src/usermetricsservice/Infographic.cpp 2014-04-03 13:02:15 +0000 |
2976 | @@ -0,0 +1,27 @@ |
2977 | +/* |
2978 | + * Copyright (C) 2014 Canonical, Ltd. |
2979 | + * |
2980 | + * This program is free software; you can redistribute it and/or modify |
2981 | + * it under the terms of the GNU General Public License as published by |
2982 | + * the Free Software Foundation; version 3. |
2983 | + * |
2984 | + * This program is distributed in the hope that it will be useful, |
2985 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2986 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2987 | + * GNU General Public License for more details. |
2988 | + * |
2989 | + * You should have received a copy of the GNU General Public License |
2990 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2991 | + * |
2992 | + * Author: Pete Woods <pete.woods@canonical.com> |
2993 | + */ |
2994 | + |
2995 | +#include <usermetricsservice/Infographic.h> |
2996 | + |
2997 | +using namespace UserMetricsService; |
2998 | + |
2999 | +Infographic::Infographic() { |
3000 | +} |
3001 | + |
3002 | +Infographic::~Infographic() { |
3003 | +} |
3004 | |
3005 | === added file 'src/usermetricsservice/Infographic.h' |
3006 | --- src/usermetricsservice/Infographic.h 1970-01-01 00:00:00 +0000 |
3007 | +++ src/usermetricsservice/Infographic.h 2014-04-03 13:02:15 +0000 |
3008 | @@ -0,0 +1,52 @@ |
3009 | +/* |
3010 | + * Copyright (C) 2014 Canonical, Ltd. |
3011 | + * |
3012 | + * This program is free software; you can redistribute it and/or modify |
3013 | + * it under the terms of the GNU General Public License as published by |
3014 | + * the Free Software Foundation; version 3. |
3015 | + * |
3016 | + * This program is distributed in the hope that it will be useful, |
3017 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3018 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3019 | + * GNU General Public License for more details. |
3020 | + * |
3021 | + * You should have received a copy of the GNU General Public License |
3022 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3023 | + * |
3024 | + * Author: Pete Woods <pete.woods@canonical.com> |
3025 | + */ |
3026 | + |
3027 | +#ifndef USERMETRICSSERVICE_INFOGRAPHIC_H_ |
3028 | +#define USERMETRICSSERVICE_INFOGRAPHIC_H_ |
3029 | + |
3030 | +#include <QSharedPointer> |
3031 | + |
3032 | +namespace UserMetricsService { |
3033 | + |
3034 | +class Infographic: public QObject { |
3035 | +Q_OBJECT |
3036 | + |
3037 | +public: |
3038 | + typedef QSharedPointer<Infographic> Ptr; |
3039 | + |
3040 | + enum class Type { |
3041 | + INVALID, ITERATE, AGGREGATE, |
3042 | + }; |
3043 | + |
3044 | + Infographic(); |
3045 | + |
3046 | + virtual ~Infographic(); |
3047 | + |
3048 | + virtual bool isValid() const = 0; |
3049 | + |
3050 | + virtual Type type() const = 0; |
3051 | + |
3052 | +public Q_SLOTS: |
3053 | + virtual void sourcesChanged( |
3054 | + const QMultiMap<QString, QString> &changedSources, |
3055 | + const QMultiMap<QString, QString> &allSources) = 0; |
3056 | +}; |
3057 | + |
3058 | +} |
3059 | + |
3060 | +#endif /* USERMETRICSSERVICE_INFOGRAPHIC_H_ */ |
3061 | |
3062 | === added file 'src/usermetricsservice/InfographicImpl.cpp' |
3063 | --- src/usermetricsservice/InfographicImpl.cpp 1970-01-01 00:00:00 +0000 |
3064 | +++ src/usermetricsservice/InfographicImpl.cpp 2014-04-03 13:02:15 +0000 |
3065 | @@ -0,0 +1,170 @@ |
3066 | +/* |
3067 | + * Copyright (C) 2014 Canonical, Ltd. |
3068 | + * |
3069 | + * This program is free software; you can redistribute it and/or modify |
3070 | + * it under the terms of the GNU General Public License as published by |
3071 | + * the Free Software Foundation; version 3. |
3072 | + * |
3073 | + * This program is distributed in the hope that it will be useful, |
3074 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3075 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3076 | + * GNU General Public License for more details. |
3077 | + * |
3078 | + * You should have received a copy of the GNU General Public License |
3079 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3080 | + * |
3081 | + * Author: Pete Woods <pete.woods@canonical.com> |
3082 | + */ |
3083 | + |
3084 | +#include <usermetricsservice/InfographicImpl.h> |
3085 | +#include <usermetricsservice/Service.h> |
3086 | + |
3087 | +#include <QDebug> |
3088 | +#include <QFile> |
3089 | +#include <QFileInfo> |
3090 | +#include <QJsonDocument> |
3091 | +#include <QJsonParseError> |
3092 | +#include <QTemporaryFile> |
3093 | + |
3094 | +using namespace UserMetricsService; |
3095 | + |
3096 | +InfographicImpl::InfographicImpl(const QFile &path, Executor::Ptr executor, |
3097 | + ResultTransport::Ptr resultTransport) : |
3098 | + m_path(path.fileName()), m_executor(executor), m_resultTransport( |
3099 | + resultTransport), m_type(Type::INVALID), m_ruleCount(0) { |
3100 | + |
3101 | + if (!m_path.open(QIODevice::ReadOnly)) { |
3102 | + qWarning() << "Failed to open path:" << m_path.fileName(); |
3103 | + return; |
3104 | + } |
3105 | + |
3106 | + QByteArray ba(m_path.readAll()); |
3107 | + m_path.close(); |
3108 | + |
3109 | + QJsonParseError error; |
3110 | + QJsonDocument document(QJsonDocument::fromJson(ba, &error)); |
3111 | + if (error.error != QJsonParseError::NoError) { |
3112 | + qWarning() << "Failed to parse infographic JSON document:" |
3113 | + << m_path.fileName() << error.errorString(); |
3114 | + return; |
3115 | + } |
3116 | + |
3117 | + if (document.isNull() || document.isEmpty()) { |
3118 | + return; |
3119 | + } |
3120 | + |
3121 | + QFileInfo fileInfo(m_path); |
3122 | + m_id = fileInfo.completeBaseName(); |
3123 | + |
3124 | + QVariantMap map(document.toVariant().toMap()); |
3125 | + |
3126 | + m_exec = map["exec"].toString(); |
3127 | + |
3128 | + QString type = map["type"].toString().toLower(); |
3129 | + if (type == "iterate") { |
3130 | + m_type = Type::ITERATE; |
3131 | + } else if (type == "aggregate") { |
3132 | + m_type = Type::AGGREGATE; |
3133 | + } |
3134 | + |
3135 | + QVariantMap input(map["input"].toMap()); |
3136 | + QMapIterator<QString, QVariant> i(input); |
3137 | + while (i.hasNext()) { |
3138 | + i.next(); |
3139 | + QStringList rules(i.value().toStringList()); |
3140 | + auto list = m_rules.insert(i.key(), QList<QRegularExpression>()); |
3141 | + for (const QString &rule : rules) { |
3142 | + *list << QRegularExpression(rule); |
3143 | + } |
3144 | + m_ruleCount += rules.size(); |
3145 | + } |
3146 | +} |
3147 | + |
3148 | +InfographicImpl::~InfographicImpl() { |
3149 | +} |
3150 | + |
3151 | +bool InfographicImpl::isValid() const { |
3152 | + return QFile::exists(m_exec) && m_type != Type::INVALID; |
3153 | +} |
3154 | + |
3155 | +Infographic::Type InfographicImpl::type() const { |
3156 | + return m_type; |
3157 | +} |
3158 | + |
3159 | +void InfographicImpl::sourcesChanged( |
3160 | + const QMultiMap<QString, QString> &changedSources, |
3161 | + const QMultiMap<QString, QString> &allSources) { |
3162 | + switch (m_type) { |
3163 | + case Type::INVALID: |
3164 | + break; |
3165 | + case Type::ITERATE: |
3166 | + iterate(changedSources); |
3167 | + break; |
3168 | + case Type::AGGREGATE: |
3169 | + aggregate(changedSources, allSources); |
3170 | + break; |
3171 | + } |
3172 | +} |
3173 | + |
3174 | +QStringList InfographicImpl::match( |
3175 | + const QMultiMap<QString, QString>& changedSources) { |
3176 | + |
3177 | + QStringList output; |
3178 | + |
3179 | + QMapIterator<QString, QList<QRegularExpression>> iter(m_rules); |
3180 | + while (iter.hasNext()) { |
3181 | + iter.next(); |
3182 | + const QString& sourceName(iter.key()); |
3183 | + QStringList changedFiles; |
3184 | + if (sourceName == "*") { |
3185 | + changedFiles = changedSources.values(); |
3186 | + } else if (changedSources.contains(sourceName)) { |
3187 | + changedFiles = changedSources.values(sourceName); |
3188 | + } |
3189 | + |
3190 | + const QList<QRegularExpression> &watchedFiles(iter.value()); |
3191 | + for (const QRegularExpression &watchedFile : watchedFiles) { |
3192 | + for (const QString &changedFile : changedFiles) { |
3193 | + QString changedFileName(QFileInfo(changedFile).fileName()); |
3194 | + if (watchedFile.match(changedFileName).hasMatch()) { |
3195 | + output << changedFile; |
3196 | + } |
3197 | + } |
3198 | + } |
3199 | + } |
3200 | + return output; |
3201 | +} |
3202 | + |
3203 | +void InfographicImpl::iterate( |
3204 | + const QMultiMap<QString, QString> &changedSources) { |
3205 | + |
3206 | + for (const QString &changedFile : match(changedSources)) { |
3207 | + execute(QStringList() << changedFile); |
3208 | + } |
3209 | +} |
3210 | + |
3211 | +void InfographicImpl::aggregate( |
3212 | + const QMultiMap<QString, QString> &changedSources, |
3213 | + const QMultiMap<QString, QString> &allSources) { |
3214 | + |
3215 | + if (match(changedSources).isEmpty()) { |
3216 | + return; |
3217 | + } |
3218 | + |
3219 | + // If we get a match for every rule |
3220 | + QStringList matches(match(allSources)); |
3221 | + if (m_ruleCount == matches.size()) { |
3222 | + execute(matches); |
3223 | + } |
3224 | +} |
3225 | + |
3226 | +void InfographicImpl::execute(const QStringList &arguments) { |
3227 | + QByteArray ba(m_executor->execute(m_exec, arguments)); |
3228 | + |
3229 | + if (ba.isEmpty()) { |
3230 | + qWarning() << "No data provided by infographic" << m_exec; |
3231 | + return; |
3232 | + } |
3233 | + |
3234 | + m_resultTransport->send(m_id, arguments, ba); |
3235 | +} |
3236 | |
3237 | === added file 'src/usermetricsservice/InfographicImpl.h' |
3238 | --- src/usermetricsservice/InfographicImpl.h 1970-01-01 00:00:00 +0000 |
3239 | +++ src/usermetricsservice/InfographicImpl.h 2014-04-03 13:02:15 +0000 |
3240 | @@ -0,0 +1,79 @@ |
3241 | +/* |
3242 | + * Copyright (C) 2014 Canonical, Ltd. |
3243 | + * |
3244 | + * This program is free software; you can redistribute it and/or modify |
3245 | + * it under the terms of the GNU General Public License as published by |
3246 | + * the Free Software Foundation; version 3. |
3247 | + * |
3248 | + * This program is distributed in the hope that it will be useful, |
3249 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3250 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3251 | + * GNU General Public License for more details. |
3252 | + * |
3253 | + * You should have received a copy of the GNU General Public License |
3254 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3255 | + * |
3256 | + * Author: Pete Woods <pete.woods@canonical.com> |
3257 | + */ |
3258 | + |
3259 | +#ifndef USERMETRICSSERVICE_INFOGRAPHICIMPL_H_ |
3260 | +#define USERMETRICSSERVICE_INFOGRAPHICIMPL_H_ |
3261 | + |
3262 | +#include <usermetricsservice/Executor.h> |
3263 | +#include <usermetricsservice/Infographic.h> |
3264 | +#include <usermetricsservice/ResultTransport.h> |
3265 | + |
3266 | +#include <QFile> |
3267 | +#include <QMap> |
3268 | +#include <QRegularExpression> |
3269 | +#include <QString> |
3270 | +#include <QStringList> |
3271 | +#include <QVariant> |
3272 | + |
3273 | +namespace UserMetricsService { |
3274 | + |
3275 | +class InfographicImpl: public Infographic { |
3276 | +public: |
3277 | + InfographicImpl(const QFile &path, Executor::Ptr executor, |
3278 | + ResultTransport::Ptr resultTransport); |
3279 | + |
3280 | + virtual ~InfographicImpl(); |
3281 | + |
3282 | + bool isValid() const; |
3283 | + |
3284 | + Type type() const; |
3285 | + |
3286 | + void sourcesChanged(const QMultiMap<QString, QString> &changedSources, |
3287 | + const QMultiMap<QString, QString> &allSources); |
3288 | + |
3289 | +protected: |
3290 | + void iterate(const QMultiMap<QString, QString> &changedSources); |
3291 | + |
3292 | + void aggregate(const QMultiMap<QString, QString> &changedSources, |
3293 | + const QMultiMap<QString, QString> &allSources); |
3294 | + |
3295 | + void execute(const QStringList &args); |
3296 | + |
3297 | + QStringList match(const QMultiMap<QString, QString>& changedSources); |
3298 | + |
3299 | + QFile m_path; |
3300 | + |
3301 | + Executor::Ptr m_executor; |
3302 | + |
3303 | + ResultTransport::Ptr m_resultTransport; |
3304 | + |
3305 | + QString m_exec; |
3306 | + |
3307 | + Type m_type; |
3308 | + |
3309 | + QMap<QString, QList<QRegularExpression>> m_rules; |
3310 | + |
3311 | + int m_ruleCount; |
3312 | + |
3313 | + QString m_id; |
3314 | + |
3315 | +}; |
3316 | + |
3317 | +} |
3318 | + |
3319 | +#endif /* USERMETRICSSERVICE_INFOGRAPHICIMPL_H_ */ |
3320 | |
3321 | === added file 'src/usermetricsservice/QProcessExecutor.cpp' |
3322 | --- src/usermetricsservice/QProcessExecutor.cpp 1970-01-01 00:00:00 +0000 |
3323 | +++ src/usermetricsservice/QProcessExecutor.cpp 2014-04-03 13:02:15 +0000 |
3324 | @@ -0,0 +1,75 @@ |
3325 | +/* |
3326 | + * Copyright (C) 2014 Canonical, Ltd. |
3327 | + * |
3328 | + * This program is free software; you can redistribute it and/or modify |
3329 | + * it under the terms of the GNU General Public License as published by |
3330 | + * the Free Software Foundation; version 3. |
3331 | + * |
3332 | + * This program is distributed in the hope that it will be useful, |
3333 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3334 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3335 | + * GNU General Public License for more details. |
3336 | + * |
3337 | + * You should have received a copy of the GNU General Public License |
3338 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3339 | + * |
3340 | + * Author: Pete Woods <pete.woods@canonical.com> |
3341 | + */ |
3342 | + |
3343 | +#include <usermetricsservice/QProcessExecutor.h> |
3344 | + |
3345 | +#include <QDebug> |
3346 | +#include <QProcess> |
3347 | +#include <QThread> |
3348 | + |
3349 | +using namespace UserMetricsService; |
3350 | + |
3351 | +QProcessExecutor::QProcessExecutor(const QDir &cacheDirectory, |
3352 | + const QString &aaExec) : |
3353 | + m_aaExec(aaExec) { |
3354 | + |
3355 | + m_usermetricsDirectory = cacheDirectory.filePath("usermetrics"); |
3356 | + m_tempDirectory = m_usermetricsDirectory.filePath("tmp"); |
3357 | +} |
3358 | + |
3359 | +QProcessExecutor::~QProcessExecutor() { |
3360 | +} |
3361 | + |
3362 | +QByteArray QProcessExecutor::execute(const QString &program, |
3363 | + const QStringList &arguments) { |
3364 | + |
3365 | + m_tempDirectory.removeRecursively(); |
3366 | + m_usermetricsDirectory.mkpath("tmp"); |
3367 | + |
3368 | + QByteArray output; |
3369 | + |
3370 | + QStringList finalArguments; |
3371 | + finalArguments << program; |
3372 | + for (int i(0); i < arguments.size(); ++i) { |
3373 | + const QString &argument(arguments[i]); |
3374 | + QString destination( |
3375 | + m_tempDirectory.filePath(QString::number(i) + ".svg")); |
3376 | + if (!QFile::copy(argument, destination)) { |
3377 | + qWarning() << "Failed to copy file" << argument << destination; |
3378 | + return output; |
3379 | + } |
3380 | + finalArguments << destination; |
3381 | + } |
3382 | + |
3383 | + QProcess process; |
3384 | + |
3385 | + process.start(m_aaExec, finalArguments); |
3386 | + |
3387 | + if (process.waitForFinished(5000)) { |
3388 | + output = process.readAllStandardOutput(); |
3389 | + QByteArray error(process.readAllStandardError()); |
3390 | + if (!error.isEmpty()) { |
3391 | + qWarning() << error; |
3392 | + } |
3393 | + } else { |
3394 | + process.kill(); |
3395 | + } |
3396 | + |
3397 | + return output; |
3398 | +} |
3399 | + |
3400 | |
3401 | === added file 'src/usermetricsservice/QProcessExecutor.h' |
3402 | --- src/usermetricsservice/QProcessExecutor.h 1970-01-01 00:00:00 +0000 |
3403 | +++ src/usermetricsservice/QProcessExecutor.h 2014-04-03 13:02:15 +0000 |
3404 | @@ -0,0 +1,46 @@ |
3405 | +/* |
3406 | + * Copyright (C) 2014 Canonical, Ltd. |
3407 | + * |
3408 | + * This program is free software; you can redistribute it and/or modify |
3409 | + * it under the terms of the GNU General Public License as published by |
3410 | + * the Free Software Foundation; version 3. |
3411 | + * |
3412 | + * This program is distributed in the hope that it will be useful, |
3413 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3414 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3415 | + * GNU General Public License for more details. |
3416 | + * |
3417 | + * You should have received a copy of the GNU General Public License |
3418 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3419 | + * |
3420 | + * Author: Pete Woods <pete.woods@canonical.com> |
3421 | + */ |
3422 | + |
3423 | +#ifndef USERMETRICSSERVICE_QPROCESSEXECUTOR_H_ |
3424 | +#define USERMETRICSSERVICE_QPROCESSEXECUTOR_H_ |
3425 | + |
3426 | +#include <usermetricsservice/Executor.h> |
3427 | + |
3428 | +#include <QDir> |
3429 | + |
3430 | +namespace UserMetricsService { |
3431 | + |
3432 | +class QProcessExecutor: public Executor { |
3433 | +public: |
3434 | + QProcessExecutor(const QDir &cacheDirectory, const QString &aaExec); |
3435 | + |
3436 | + virtual ~QProcessExecutor(); |
3437 | + |
3438 | + QByteArray execute(const QString &program, const QStringList &arguments); |
3439 | + |
3440 | +protected: |
3441 | + QDir m_usermetricsDirectory; |
3442 | + |
3443 | + QDir m_tempDirectory; |
3444 | + |
3445 | + QString m_aaExec; |
3446 | +}; |
3447 | + |
3448 | +} |
3449 | + |
3450 | +#endif /* USERMETRICSSERVICE_QPROCESSEXECUTOR_H_ */ |
3451 | |
3452 | === added file 'src/usermetricsservice/ResultTransport.cpp' |
3453 | --- src/usermetricsservice/ResultTransport.cpp 1970-01-01 00:00:00 +0000 |
3454 | +++ src/usermetricsservice/ResultTransport.cpp 2014-04-03 13:02:15 +0000 |
3455 | @@ -0,0 +1,27 @@ |
3456 | +/* |
3457 | + * Copyright (C) 2014 Canonical, Ltd. |
3458 | + * |
3459 | + * This program is free software; you can redistribute it and/or modify |
3460 | + * it under the terms of the GNU General Public License as published by |
3461 | + * the Free Software Foundation; version 3. |
3462 | + * |
3463 | + * This program is distributed in the hope that it will be useful, |
3464 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3465 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3466 | + * GNU General Public License for more details. |
3467 | + * |
3468 | + * You should have received a copy of the GNU General Public License |
3469 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3470 | + * |
3471 | + * Author: Pete Woods <pete.woods@canonical.com> |
3472 | + */ |
3473 | + |
3474 | +#include <usermetricsservice/ResultTransport.h> |
3475 | + |
3476 | +using namespace UserMetricsService; |
3477 | + |
3478 | +ResultTransport::ResultTransport() { |
3479 | +} |
3480 | + |
3481 | +ResultTransport::~ResultTransport() { |
3482 | +} |
3483 | |
3484 | === added file 'src/usermetricsservice/ResultTransport.h' |
3485 | --- src/usermetricsservice/ResultTransport.h 1970-01-01 00:00:00 +0000 |
3486 | +++ src/usermetricsservice/ResultTransport.h 2014-04-03 13:02:15 +0000 |
3487 | @@ -0,0 +1,45 @@ |
3488 | +/* |
3489 | + * Copyright (C) 2014 Canonical, Ltd. |
3490 | + * |
3491 | + * This program is free software; you can redistribute it and/or modify |
3492 | + * it under the terms of the GNU General Public License as published by |
3493 | + * the Free Software Foundation; version 3. |
3494 | + * |
3495 | + * This program is distributed in the hope that it will be useful, |
3496 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3497 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3498 | + * GNU General Public License for more details. |
3499 | + * |
3500 | + * You should have received a copy of the GNU General Public License |
3501 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3502 | + * |
3503 | + * Author: Pete Woods <pete.woods@canonical.com> |
3504 | + */ |
3505 | + |
3506 | +#ifndef USERMETRICSSERVICE_RESULTTRANSPORT_H_ |
3507 | +#define USERMETRICSSERVICE_RESULTTRANSPORT_H_ |
3508 | + |
3509 | +#include <QByteArray> |
3510 | +#include <QString> |
3511 | +#include <QStringList> |
3512 | +#include <QSharedPointer> |
3513 | + |
3514 | +namespace UserMetricsService { |
3515 | + |
3516 | +class ResultTransport { |
3517 | +public: |
3518 | + typedef QSharedPointer<ResultTransport> Ptr; |
3519 | + |
3520 | + ResultTransport(); |
3521 | + |
3522 | + virtual ~ResultTransport(); |
3523 | + |
3524 | + virtual void clear() = 0; |
3525 | + |
3526 | + virtual void send(const QString &id, const QStringList &arguments, |
3527 | + const QByteArray &ba) = 0; |
3528 | +}; |
3529 | + |
3530 | +} |
3531 | + |
3532 | +#endif /* USERMETRICSSERVICE_RESULTTRANSPORT_H_ */ |
3533 | |
3534 | === added file 'src/usermetricsservice/ResultTransportImpl.cpp' |
3535 | --- src/usermetricsservice/ResultTransportImpl.cpp 1970-01-01 00:00:00 +0000 |
3536 | +++ src/usermetricsservice/ResultTransportImpl.cpp 2014-04-03 13:02:15 +0000 |
3537 | @@ -0,0 +1,66 @@ |
3538 | +/* |
3539 | + * Copyright (C) 2014 Canonical, Ltd. |
3540 | + * |
3541 | + * This program is free software; you can redistribute it and/or modify |
3542 | + * it under the terms of the GNU General Public License as published by |
3543 | + * the Free Software Foundation; version 3. |
3544 | + * |
3545 | + * This program is distributed in the hope that it will be useful, |
3546 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3547 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3548 | + * GNU General Public License for more details. |
3549 | + * |
3550 | + * You should have received a copy of the GNU General Public License |
3551 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3552 | + * |
3553 | + * Author: Pete Woods <pete.woods@canonical.com> |
3554 | + */ |
3555 | + |
3556 | +#include <usermetricsservice/ResultTransportImpl.h> |
3557 | + |
3558 | +#include <QDebug> |
3559 | +#include <sys/stat.h> |
3560 | + |
3561 | +using namespace UserMetricsService; |
3562 | + |
3563 | +ResultTransportImpl::ResultTransportImpl( |
3564 | + QSharedPointer<ComCanonicalInfographicsInterface> infographicService) : |
3565 | + m_infographicService(infographicService) { |
3566 | +} |
3567 | + |
3568 | +ResultTransportImpl::~ResultTransportImpl() { |
3569 | +} |
3570 | + |
3571 | +void ResultTransportImpl::clear() { |
3572 | + m_infographicService->clear().waitForFinished(); |
3573 | +} |
3574 | + |
3575 | +void ResultTransportImpl::send(const QString &id, const QStringList &arguments, |
3576 | + const QByteArray &ba) { |
3577 | + QFile fifo; |
3578 | + { |
3579 | + QTemporaryFile tempFile; |
3580 | + tempFile.open(); |
3581 | + tempFile.close(); |
3582 | + fifo.setFileName(tempFile.fileName()); |
3583 | + } |
3584 | + |
3585 | + int err = mkfifo(fifo.fileName().toUtf8().constData(), 0644); |
3586 | + if (err != 0) { |
3587 | + // someone is trying something naughty |
3588 | + qWarning() << "FIFO path already existed" << fifo.fileName(); |
3589 | + return; |
3590 | + } |
3591 | + |
3592 | + QDBusPendingReply<> reply( |
3593 | + m_infographicService->update(id, arguments, fifo.fileName())); |
3594 | + |
3595 | + if (fifo.open(QIODevice::WriteOnly)) { |
3596 | + fifo.write(ba); |
3597 | + fifo.close(); |
3598 | + } |
3599 | + |
3600 | + reply.waitForFinished(); |
3601 | + |
3602 | + fifo.remove(); |
3603 | +} |
3604 | |
3605 | === added file 'src/usermetricsservice/ResultTransportImpl.h' |
3606 | --- src/usermetricsservice/ResultTransportImpl.h 1970-01-01 00:00:00 +0000 |
3607 | +++ src/usermetricsservice/ResultTransportImpl.h 2014-04-03 13:02:15 +0000 |
3608 | @@ -0,0 +1,45 @@ |
3609 | +/* |
3610 | + * Copyright (C) 2014 Canonical, Ltd. |
3611 | + * |
3612 | + * This program is free software; you can redistribute it and/or modify |
3613 | + * it under the terms of the GNU General Public License as published by |
3614 | + * the Free Software Foundation; version 3. |
3615 | + * |
3616 | + * This program is distributed in the hope that it will be useful, |
3617 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3618 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3619 | + * GNU General Public License for more details. |
3620 | + * |
3621 | + * You should have received a copy of the GNU General Public License |
3622 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3623 | + * |
3624 | + * Author: Pete Woods <pete.woods@canonical.com> |
3625 | + */ |
3626 | + |
3627 | +#ifndef USERMETRICSSERVICE_RESULTTRANSPORTIMPL_H_ |
3628 | +#define USERMETRICSSERVICE_RESULTTRANSPORTIMPL_H_ |
3629 | + |
3630 | +#include <libusermetricscommon/InfographicsInterface.h> |
3631 | +#include <usermetricsservice/ResultTransport.h> |
3632 | + |
3633 | +namespace UserMetricsService { |
3634 | + |
3635 | +class ResultTransportImpl: public ResultTransport { |
3636 | +public: |
3637 | + ResultTransportImpl( |
3638 | + QSharedPointer<ComCanonicalInfographicsInterface> infographicService); |
3639 | + |
3640 | + virtual ~ResultTransportImpl(); |
3641 | + |
3642 | + void clear(); |
3643 | + |
3644 | + void send(const QString &id, const QStringList &arguments, |
3645 | + const QByteArray &ba); |
3646 | + |
3647 | +protected: |
3648 | + QSharedPointer<ComCanonicalInfographicsInterface> m_infographicService; |
3649 | +}; |
3650 | + |
3651 | +} |
3652 | + |
3653 | +#endif /* USERMETRICSSERVICE_RESULTTRANSPORTIMPL_H_ */ |
3654 | |
3655 | === added file 'src/usermetricsservice/Service.cpp' |
3656 | --- src/usermetricsservice/Service.cpp 1970-01-01 00:00:00 +0000 |
3657 | +++ src/usermetricsservice/Service.cpp 2014-04-03 13:02:15 +0000 |
3658 | @@ -0,0 +1,27 @@ |
3659 | +/* |
3660 | + * Copyright (C) 2014 Canonical, Ltd. |
3661 | + * |
3662 | + * This program is free software; you can redistribute it and/or modify |
3663 | + * it under the terms of the GNU General Public License as published by |
3664 | + * the Free Software Foundation; version 3. |
3665 | + * |
3666 | + * This program is distributed in the hope that it will be useful, |
3667 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3668 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3669 | + * GNU General Public License for more details. |
3670 | + * |
3671 | + * You should have received a copy of the GNU General Public License |
3672 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3673 | + * |
3674 | + * Author: Pete Woods <pete.woods@canonical.com> |
3675 | + */ |
3676 | + |
3677 | +#include <usermetricsservice/Service.h> |
3678 | + |
3679 | +using namespace UserMetricsService; |
3680 | + |
3681 | +Service::Service() { |
3682 | +} |
3683 | + |
3684 | +Service::~Service() { |
3685 | +} |
3686 | |
3687 | === added file 'src/usermetricsservice/Service.h' |
3688 | --- src/usermetricsservice/Service.h 1970-01-01 00:00:00 +0000 |
3689 | +++ src/usermetricsservice/Service.h 2014-04-03 13:02:15 +0000 |
3690 | @@ -0,0 +1,45 @@ |
3691 | +/* |
3692 | + * Copyright (C) 2014 Canonical, Ltd. |
3693 | + * |
3694 | + * This program is free software; you can redistribute it and/or modify |
3695 | + * it under the terms of the GNU General Public License as published by |
3696 | + * the Free Software Foundation; version 3. |
3697 | + * |
3698 | + * This program is distributed in the hope that it will be useful, |
3699 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3700 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3701 | + * GNU General Public License for more details. |
3702 | + * |
3703 | + * You should have received a copy of the GNU General Public License |
3704 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3705 | + * |
3706 | + * Author: Pete Woods <pete.woods@canonical.com> |
3707 | + */ |
3708 | + |
3709 | +#ifndef USERMETRICSSERVICE_SERVICE_H_ |
3710 | +#define USERMETRICSSERVICE_SERVICE_H_ |
3711 | + |
3712 | +#include <QObject> |
3713 | +#include <QMultiMap> |
3714 | +#include <QSharedPointer> |
3715 | +#include <QString> |
3716 | + |
3717 | +namespace UserMetricsService { |
3718 | + |
3719 | +class Service: public QObject { |
3720 | +Q_OBJECT |
3721 | +public: |
3722 | + typedef QSharedPointer<Service> Ptr; |
3723 | + |
3724 | + Service(); |
3725 | + |
3726 | + virtual ~Service(); |
3727 | + |
3728 | +Q_SIGNALS: |
3729 | + void sourcesChanged(const QMultiMap<QString, QString> &changedSources, |
3730 | + const QMultiMap<QString, QString> &allSources); |
3731 | +}; |
3732 | + |
3733 | +} |
3734 | + |
3735 | +#endif /* USERMETRICSSERVICE_SERVICE_H_ */ |
3736 | |
3737 | === added file 'src/usermetricsservice/ServiceImpl.cpp' |
3738 | --- src/usermetricsservice/ServiceImpl.cpp 1970-01-01 00:00:00 +0000 |
3739 | +++ src/usermetricsservice/ServiceImpl.cpp 2014-04-03 13:02:15 +0000 |
3740 | @@ -0,0 +1,163 @@ |
3741 | +/* |
3742 | + * Copyright (C) 2014 Canonical, Ltd. |
3743 | + * |
3744 | + * This program is free software; you can redistribute it and/or modify |
3745 | + * it under the terms of the GNU General Public License as published by |
3746 | + * the Free Software Foundation; version 3. |
3747 | + * |
3748 | + * This program is distributed in the hope that it will be useful, |
3749 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3750 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3751 | + * GNU General Public License for more details. |
3752 | + * |
3753 | + * You should have received a copy of the GNU General Public License |
3754 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3755 | + * |
3756 | + * Author: Pete Woods <pete.woods@canonical.com> |
3757 | + */ |
3758 | + |
3759 | +#include <usermetricsservice/ServiceImpl.h> |
3760 | + |
3761 | +#include <QDebug> |
3762 | +#include <QStringList> |
3763 | +#include <stdexcept> |
3764 | + |
3765 | +using namespace UserMetricsCommon; |
3766 | +using namespace UserMetricsService; |
3767 | +using namespace std; |
3768 | + |
3769 | +ServiceImpl::ServiceImpl(const QDir &cacheDirectory, |
3770 | + const QDir &packageInfographics, FileUtils::Ptr fileUtils, |
3771 | + ResultTransport::Ptr resultTransport, Factory &factory) : |
3772 | + m_cacheDirectory(cacheDirectory), m_fileUtils(fileUtils), m_resultTransport( |
3773 | + resultTransport), m_factory(factory) { |
3774 | + QDir usermetricsDirectory(cacheDirectory.filePath("usermetrics")); |
3775 | + |
3776 | + if (!usermetricsDirectory.mkpath("infographics")) { |
3777 | + throw logic_error("Cannot create infographics directory"); |
3778 | + } |
3779 | + |
3780 | + if (!usermetricsDirectory.mkpath("sources")) { |
3781 | + throw logic_error("Cannot create sources directory"); |
3782 | + } |
3783 | + |
3784 | + m_infographicDirectories << usermetricsDirectory.filePath("infographics"); |
3785 | + m_infographicDirectories << packageInfographics.path(); |
3786 | + m_sourcesDirectory = usermetricsDirectory.filePath("sources"); |
3787 | + |
3788 | + m_timer.setSingleShot(true); |
3789 | + |
3790 | + connect(&m_infographicWatcher, &QFileSystemWatcher::directoryChanged, this, |
3791 | + &ServiceImpl::updateInfographicList); |
3792 | + connect(&m_sourcesWatcher, &QFileSystemWatcher::directoryChanged, this, |
3793 | + &ServiceImpl::updateSourcesList); |
3794 | + |
3795 | + connect(&m_timer, &QTimer::timeout, this, &ServiceImpl::flushQueue); |
3796 | + |
3797 | + updateInfographicList(); |
3798 | + updateSourcesList(); |
3799 | + |
3800 | + m_infographicWatcher.addPaths(m_infographicDirectories); |
3801 | + m_sourcesWatcher.addPath(m_sourcesDirectory.path()); |
3802 | + |
3803 | + m_resultTransport->clear(); |
3804 | + |
3805 | + QMultiMap<QString, QString> sources(allSources()); |
3806 | + sourcesChanged(sources, sources); |
3807 | +} |
3808 | + |
3809 | +ServiceImpl::~ServiceImpl() { |
3810 | +} |
3811 | + |
3812 | +void ServiceImpl::updateInfographicList() { |
3813 | + QSet<QString> names; |
3814 | + |
3815 | + for (const QString &directory : m_infographicDirectories) { |
3816 | + names.unite(m_fileUtils->listDirectory(directory, QDir::Files).toSet()); |
3817 | + } |
3818 | + |
3819 | + // Remove deleted infographics |
3820 | + QSet<QString> toRemove(m_infographics.keys().toSet().subtract(names)); |
3821 | + for (const QString &name : toRemove) { |
3822 | + m_infographics.take(name); |
3823 | + } |
3824 | + |
3825 | + // Work out the names we need to add |
3826 | + names.subtract(m_infographics.keys().toSet()); |
3827 | + for (const QString &name : names) { |
3828 | + Infographic::Ptr infographic(m_factory.newInfographic(name)); |
3829 | + m_infographics.insert(name, infographic); |
3830 | + if (infographic->isValid()) { |
3831 | + connect(this, &Service::sourcesChanged, infographic.data(), |
3832 | + &Infographic::sourcesChanged); |
3833 | + } |
3834 | + } |
3835 | +} |
3836 | + |
3837 | +void ServiceImpl::updateSourcesList() { |
3838 | + QSet<QString> fullNames( |
3839 | + m_fileUtils->listDirectory(m_sourcesDirectory, QDir::Files).toSet()); |
3840 | + |
3841 | + QSet<QString> names; |
3842 | + for (const QString &name : fullNames) { |
3843 | + QFileInfo fileInfo(name); |
3844 | + QString shortName(fileInfo.completeBaseName()); |
3845 | + m_fileUtils->shortApplicationId(shortName); |
3846 | + QDir applicationDirectory(m_cacheDirectory.filePath(shortName)); |
3847 | + applicationDirectory.mkpath("usermetrics"); |
3848 | + names << applicationDirectory.filePath("usermetrics"); |
3849 | + } |
3850 | + |
3851 | + // Remove deleted sources |
3852 | + QSet<QString> toRemove(m_sources.keys().toSet().subtract(names)); |
3853 | + for (const QString &name : toRemove) { |
3854 | + m_sources.take(name); |
3855 | + } |
3856 | + |
3857 | + // Work out the names we need to add |
3858 | + names.subtract(m_sources.keys().toSet()); |
3859 | + for (const QString &name : names) { |
3860 | + SourceDirectory::Ptr sourceDirectory( |
3861 | + m_factory.newSourceDirectory(name)); |
3862 | + connect(sourceDirectory.data(), &SourceDirectory::sourceChanged, this, |
3863 | + &ServiceImpl::sourceChanged); |
3864 | + m_sources.insert(name, sourceDirectory); |
3865 | + } |
3866 | +} |
3867 | + |
3868 | +void ServiceImpl::sourceChanged(const QDir &directory, |
3869 | + const QString &fileName) { |
3870 | + QFileInfo directoryInfo(directory.path()); |
3871 | + QString applicationId(directoryInfo.dir().dirName()); |
3872 | + m_fileUtils->shortApplicationId(applicationId); |
3873 | + |
3874 | + if (m_changedSources.constFind(applicationId, fileName) |
3875 | + == m_changedSources.constEnd()) { |
3876 | + m_changedSources.insert(applicationId, fileName); |
3877 | + } |
3878 | + m_timer.start(100); |
3879 | +} |
3880 | + |
3881 | +QMultiMap<QString, QString> ServiceImpl::allSources() { |
3882 | + QMultiMap<QString, QString> sources; |
3883 | + |
3884 | + QMapIterator<QString, SourceDirectory::Ptr> iter(m_sources); |
3885 | + while (iter.hasNext()) { |
3886 | + iter.next(); |
3887 | + |
3888 | + QFileInfo directoryInfo(iter.key()); |
3889 | + QString applicationId(directoryInfo.dir().dirName()); |
3890 | + m_fileUtils->shortApplicationId(applicationId); |
3891 | + |
3892 | + for (const QString &filePath : iter.value()->files()) { |
3893 | + sources.insert(applicationId, filePath); |
3894 | + } |
3895 | + } |
3896 | + |
3897 | + return sources; |
3898 | +} |
3899 | + |
3900 | +void ServiceImpl::flushQueue() { |
3901 | + sourcesChanged(m_changedSources, allSources()); |
3902 | + m_changedSources.clear(); |
3903 | +} |
3904 | |
3905 | === added file 'src/usermetricsservice/ServiceImpl.h' |
3906 | --- src/usermetricsservice/ServiceImpl.h 1970-01-01 00:00:00 +0000 |
3907 | +++ src/usermetricsservice/ServiceImpl.h 2014-04-03 13:02:15 +0000 |
3908 | @@ -0,0 +1,82 @@ |
3909 | +/* |
3910 | + * Copyright (C) 2014 Canonical, Ltd. |
3911 | + * |
3912 | + * This program is free software; you can redistribute it and/or modify |
3913 | + * it under the terms of the GNU General Public License as published by |
3914 | + * the Free Software Foundation; version 3. |
3915 | + * |
3916 | + * This program is distributed in the hope that it will be useful, |
3917 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3918 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3919 | + * GNU General Public License for more details. |
3920 | + * |
3921 | + * You should have received a copy of the GNU General Public License |
3922 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3923 | + * |
3924 | + * Author: Pete Woods <pete.woods@canonical.com> |
3925 | + */ |
3926 | + |
3927 | +#ifndef USERMETRICSSERVICE_SERVICEIMPL_H_ |
3928 | +#define USERMETRICSSERVICE_SERVICEIMPL_H_ |
3929 | + |
3930 | +#include <usermetricsservice/Factory.h> |
3931 | + |
3932 | +#include <QFileSystemWatcher> |
3933 | +#include <QDir> |
3934 | +#include <QMap> |
3935 | +#include <QMultiMap> |
3936 | +#include <QString> |
3937 | +#include <QTimer> |
3938 | + |
3939 | +namespace UserMetricsService { |
3940 | + |
3941 | +class ServiceImpl: public Service { |
3942 | +Q_OBJECT |
3943 | + |
3944 | +public: |
3945 | + ServiceImpl(const QDir &cacheDirectory, const QDir &packageInfographics, |
3946 | + UserMetricsCommon::FileUtils::Ptr fileUtils, |
3947 | + ResultTransport::Ptr resultTransport, Factory &factory); |
3948 | + |
3949 | + virtual ~ServiceImpl(); |
3950 | + |
3951 | +protected Q_SLOTS: |
3952 | + void updateInfographicList(); |
3953 | + |
3954 | + void updateSourcesList(); |
3955 | + |
3956 | + void sourceChanged(const QDir &directory, const QString &fileName); |
3957 | + |
3958 | + void flushQueue(); |
3959 | + |
3960 | + QMultiMap<QString, QString> allSources(); |
3961 | + |
3962 | +protected: |
3963 | + QDir m_cacheDirectory; |
3964 | + |
3965 | + UserMetricsCommon::FileUtils::Ptr m_fileUtils; |
3966 | + |
3967 | + ResultTransport::Ptr m_resultTransport; |
3968 | + |
3969 | + Factory &m_factory; |
3970 | + |
3971 | + QTimer m_timer; |
3972 | + |
3973 | + QList<QString> m_infographicDirectories; |
3974 | + |
3975 | + QFileSystemWatcher m_infographicWatcher; |
3976 | + |
3977 | + QDir m_sourcesDirectory; |
3978 | + |
3979 | + QFileSystemWatcher m_sourcesWatcher; |
3980 | + |
3981 | + QMap<QString, Infographic::Ptr> m_infographics; |
3982 | + |
3983 | + QMap<QString, SourceDirectory::Ptr> m_sources; |
3984 | + |
3985 | + QMultiMap<QString, QString> m_changedSources; |
3986 | +}; |
3987 | + |
3988 | +} |
3989 | + |
3990 | +#endif /* USERMETRICSSERVICE_SERVICEIMPL_H_ */ |
3991 | |
3992 | === added file 'src/usermetricsservice/SourceDirectory.cpp' |
3993 | --- src/usermetricsservice/SourceDirectory.cpp 1970-01-01 00:00:00 +0000 |
3994 | +++ src/usermetricsservice/SourceDirectory.cpp 2014-04-03 13:02:15 +0000 |
3995 | @@ -0,0 +1,27 @@ |
3996 | +/* |
3997 | + * Copyright (C) 2014 Canonical, Ltd. |
3998 | + * |
3999 | + * This program is free software; you can redistribute it and/or modify |
4000 | + * it under the terms of the GNU General Public License as published by |
4001 | + * the Free Software Foundation; version 3. |
4002 | + * |
4003 | + * This program is distributed in the hope that it will be useful, |
4004 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4005 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4006 | + * GNU General Public License for more details. |
4007 | + * |
4008 | + * You should have received a copy of the GNU General Public License |
4009 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4010 | + * |
4011 | + * Author: Pete Woods <pete.woods@canonical.com> |
4012 | + */ |
4013 | + |
4014 | +#include <usermetricsservice/SourceDirectory.h> |
4015 | + |
4016 | +using namespace UserMetricsService; |
4017 | + |
4018 | +SourceDirectory::SourceDirectory() { |
4019 | +} |
4020 | + |
4021 | +SourceDirectory::~SourceDirectory() { |
4022 | +} |
4023 | |
4024 | === added file 'src/usermetricsservice/SourceDirectory.h' |
4025 | --- src/usermetricsservice/SourceDirectory.h 1970-01-01 00:00:00 +0000 |
4026 | +++ src/usermetricsservice/SourceDirectory.h 2014-04-03 13:02:15 +0000 |
4027 | @@ -0,0 +1,45 @@ |
4028 | +/* |
4029 | + * Copyright (C) 2014 Canonical, Ltd. |
4030 | + * |
4031 | + * This program is free software; you can redistribute it and/or modify |
4032 | + * it under the terms of the GNU General Public License as published by |
4033 | + * the Free Software Foundation; version 3. |
4034 | + * |
4035 | + * This program is distributed in the hope that it will be useful, |
4036 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4037 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4038 | + * GNU General Public License for more details. |
4039 | + * |
4040 | + * You should have received a copy of the GNU General Public License |
4041 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4042 | + * |
4043 | + * Author: Pete Woods <pete.woods@canonical.com> |
4044 | + */ |
4045 | + |
4046 | +#ifndef USERMETRICSSERVICE_SOURCEDIRECTORY_H_ |
4047 | +#define USERMETRICSSERVICE_SOURCEDIRECTORY_H_ |
4048 | + |
4049 | +#include <QDir> |
4050 | +#include <QObject> |
4051 | +#include <QSharedPointer> |
4052 | + |
4053 | +namespace UserMetricsService { |
4054 | + |
4055 | +class SourceDirectory: public QObject { |
4056 | +Q_OBJECT |
4057 | +public: |
4058 | + typedef QSharedPointer<SourceDirectory> Ptr; |
4059 | + |
4060 | + SourceDirectory(); |
4061 | + |
4062 | + virtual ~SourceDirectory(); |
4063 | + |
4064 | + virtual QStringList files() = 0; |
4065 | + |
4066 | +Q_SIGNALS: |
4067 | + void sourceChanged(const QDir &directory, const QString &file); |
4068 | +}; |
4069 | + |
4070 | +} |
4071 | + |
4072 | +#endif /* USERMETRICSSERVICE_SOURCEDIRECTORY_H_ */ |
4073 | |
4074 | === added file 'src/usermetricsservice/SourceDirectoryImpl.cpp' |
4075 | --- src/usermetricsservice/SourceDirectoryImpl.cpp 1970-01-01 00:00:00 +0000 |
4076 | +++ src/usermetricsservice/SourceDirectoryImpl.cpp 2014-04-03 13:02:15 +0000 |
4077 | @@ -0,0 +1,67 @@ |
4078 | +/* |
4079 | + * Copyright (C) 2014 Canonical, Ltd. |
4080 | + * |
4081 | + * This program is free software; you can redistribute it and/or modify |
4082 | + * it under the terms of the GNU General Public License as published by |
4083 | + * the Free Software Foundation; version 3. |
4084 | + * |
4085 | + * This program is distributed in the hope that it will be useful, |
4086 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4087 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4088 | + * GNU General Public License for more details. |
4089 | + * |
4090 | + * You should have received a copy of the GNU General Public License |
4091 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4092 | + * |
4093 | + * Author: Pete Woods <pete.woods@canonical.com> |
4094 | + */ |
4095 | + |
4096 | +#include <usermetricsservice/SourceDirectoryImpl.h> |
4097 | + |
4098 | +#include <QDebug> |
4099 | + |
4100 | +using namespace UserMetricsCommon; |
4101 | +using namespace UserMetricsService; |
4102 | + |
4103 | +SourceDirectoryImpl::SourceDirectoryImpl(const QDir &path, |
4104 | + FileUtils::Ptr fileUtils) : |
4105 | + m_path(path), m_fileUtils(fileUtils) { |
4106 | + |
4107 | + m_watcher.addPath(path.path()); |
4108 | + |
4109 | + connect(&m_watcher, &QFileSystemWatcher::fileChanged, this, |
4110 | + &SourceDirectoryImpl::fileChanged); |
4111 | + connect(&m_watcher, &QFileSystemWatcher::directoryChanged, this, |
4112 | + &SourceDirectoryImpl::updateFileList); |
4113 | + |
4114 | + updateFileList(); |
4115 | +} |
4116 | + |
4117 | +SourceDirectoryImpl::~SourceDirectoryImpl() { |
4118 | +} |
4119 | + |
4120 | +void SourceDirectoryImpl::fileChanged(const QString &path) { |
4121 | + sourceChanged(m_path, path); |
4122 | +} |
4123 | + |
4124 | +void SourceDirectoryImpl::updateFileList() { |
4125 | + QSet<QString> names( |
4126 | + m_fileUtils->listDirectory(m_path, QDir::Files).toSet()); |
4127 | + |
4128 | + // Remove deleted files |
4129 | + QSet<QString> toRemove(m_watcher.files().toSet().subtract(names)); |
4130 | + if (!toRemove.isEmpty()) { |
4131 | + m_watcher.removePaths(toRemove.toList()); |
4132 | + } |
4133 | + |
4134 | + // Work out the names we need to add |
4135 | + names.subtract(m_watcher.files().toSet()); |
4136 | + for (const QString &name : names) { |
4137 | + m_watcher.addPath(name); |
4138 | + sourceChanged(m_path, name); |
4139 | + } |
4140 | +} |
4141 | + |
4142 | +QStringList SourceDirectoryImpl::files() { |
4143 | + return m_watcher.files(); |
4144 | +} |
4145 | |
4146 | === added file 'src/usermetricsservice/SourceDirectoryImpl.h' |
4147 | --- src/usermetricsservice/SourceDirectoryImpl.h 1970-01-01 00:00:00 +0000 |
4148 | +++ src/usermetricsservice/SourceDirectoryImpl.h 2014-04-03 13:02:15 +0000 |
4149 | @@ -0,0 +1,57 @@ |
4150 | +/* |
4151 | + * Copyright (C) 2014 Canonical, Ltd. |
4152 | + * |
4153 | + * This program is free software; you can redistribute it and/or modify |
4154 | + * it under the terms of the GNU General Public License as published by |
4155 | + * the Free Software Foundation; version 3. |
4156 | + * |
4157 | + * This program is distributed in the hope that it will be useful, |
4158 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4159 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4160 | + * GNU General Public License for more details. |
4161 | + * |
4162 | + * You should have received a copy of the GNU General Public License |
4163 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4164 | + * |
4165 | + * Author: Pete Woods <pete.woods@canonical.com> |
4166 | + */ |
4167 | + |
4168 | +#ifndef USERMETRICSSERVICE_SOURCEDIRECTORYIMPL_H_ |
4169 | +#define USERMETRICSSERVICE_SOURCEDIRECTORYIMPL_H_ |
4170 | + |
4171 | +#include <libusermetricscommon/FileUtils.h> |
4172 | +#include <usermetricsservice/SourceDirectory.h> |
4173 | + |
4174 | +#include <QDir> |
4175 | +#include <QFile> |
4176 | +#include <QFileSystemWatcher> |
4177 | + |
4178 | +namespace UserMetricsService { |
4179 | + |
4180 | +class SourceDirectoryImpl: public SourceDirectory { |
4181 | +Q_OBJECT |
4182 | + |
4183 | +public: |
4184 | + SourceDirectoryImpl(const QDir &path, |
4185 | + UserMetricsCommon::FileUtils::Ptr fileUtils); |
4186 | + |
4187 | + virtual ~SourceDirectoryImpl(); |
4188 | + |
4189 | + QStringList files(); |
4190 | + |
4191 | +protected Q_SLOTS: |
4192 | + void fileChanged(const QString &path); |
4193 | + |
4194 | + void updateFileList(); |
4195 | + |
4196 | +protected: |
4197 | + QDir m_path; |
4198 | + |
4199 | + UserMetricsCommon::FileUtils::Ptr m_fileUtils; |
4200 | + |
4201 | + QFileSystemWatcher m_watcher; |
4202 | +}; |
4203 | + |
4204 | +} |
4205 | + |
4206 | +#endif /* USERMETRICSSERVICE_SOURCEDIRECTORYIMPL_H_ */ |
4207 | |
4208 | === added file 'src/usermetricsservice/aa-exec.cpp' |
4209 | --- src/usermetricsservice/aa-exec.cpp 1970-01-01 00:00:00 +0000 |
4210 | +++ src/usermetricsservice/aa-exec.cpp 2014-04-03 13:02:15 +0000 |
4211 | @@ -0,0 +1,34 @@ |
4212 | +/* |
4213 | + * Copyright (C) 2014 Canonical, Ltd. |
4214 | + * |
4215 | + * This program is free software; you can redistribute it and/or modify |
4216 | + * it under the terms of the GNU General Public License as published by |
4217 | + * the Free Software Foundation; version 3. |
4218 | + * |
4219 | + * This program is distributed in the hope that it will be useful, |
4220 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4221 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4222 | + * GNU General Public License for more details. |
4223 | + * |
4224 | + * You should have received a copy of the GNU General Public License |
4225 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4226 | + * |
4227 | + * Author: Pete Woods <pete.woods@canonical.com> |
4228 | + */ |
4229 | + |
4230 | +#include <unistd.h> |
4231 | +#include <sys/apparmor.h> |
4232 | + |
4233 | +int main(int argc, char **argv) { |
4234 | + if (argc < 2) { |
4235 | + return 1; |
4236 | + } |
4237 | + |
4238 | + // Shift off the first argument |
4239 | + ++argv; |
4240 | + |
4241 | +// TODO Enable the profile switching |
4242 | +// aa_change_onexec("infographic"); |
4243 | + |
4244 | + return execv(*argv, argv); |
4245 | +} |
4246 | |
4247 | === modified file 'src/usermetricsservice/main.cpp' |
4248 | --- src/usermetricsservice/main.cpp 2014-02-04 12:07:58 +0000 |
4249 | +++ src/usermetricsservice/main.cpp 2014-04-03 13:02:15 +0000 |
4250 | @@ -1,5 +1,5 @@ |
4251 | /* |
4252 | - * Copyright (C) 2013 Canonical, Ltd. |
4253 | + * Copyright (C) 2014 Canonical, Ltd. |
4254 | * |
4255 | * This program is free software; you can redistribute it and/or modify |
4256 | * it under the terms of the GNU General Public License as published by |
4257 | @@ -16,6 +16,31 @@ |
4258 | * Author: Pete Woods <pete.woods@canonical.com> |
4259 | */ |
4260 | |
4261 | +#include <usermetricsservice/Factory.h> |
4262 | + |
4263 | +#include <QCoreApplication> |
4264 | +#include <QDebug> |
4265 | +#include <csignal> |
4266 | + |
4267 | +using namespace UserMetricsService; |
4268 | + |
4269 | +static void exitQt(int sig) { |
4270 | + Q_UNUSED(sig); |
4271 | + QCoreApplication::exit(0); |
4272 | +} |
4273 | + |
4274 | int main(int argc, char *argv[]) { |
4275 | - return 0; |
4276 | + QCoreApplication application(argc, argv); |
4277 | + |
4278 | + signal(SIGINT, &exitQt); |
4279 | + signal(SIGTERM, &exitQt); |
4280 | + |
4281 | + try { |
4282 | + Factory factory; |
4283 | + factory.singletonService(); |
4284 | + return application.exec(); |
4285 | + } catch (std::exception &e) { |
4286 | + qWarning() << "Usermetrics Service:" << e.what(); |
4287 | + return 1; |
4288 | + } |
4289 | } |
4290 | |
4291 | === modified file 'tests/CMakeLists.txt' |
4292 | --- tests/CMakeLists.txt 2014-01-03 11:40:22 +0000 |
4293 | +++ tests/CMakeLists.txt 2014-04-03 13:02:15 +0000 |
4294 | @@ -15,6 +15,11 @@ |
4295 | add_definitions(-DTEST_LOCALEDIR="${CMAKE_CURRENT_BINARY_DIR}/data") |
4296 | add_definitions(-DTEST_DATADIR="${CMAKE_CURRENT_SOURCE_DIR}/data") |
4297 | |
4298 | +set(TEST_INFOGRAPHICS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/data/infographics") |
4299 | +add_definitions(-DTEST_INFOGRAPHICS_DIR="${TEST_INFOGRAPHICS_DIR}") |
4300 | +add_definitions(-DTEST_AGGREGATE_INFOGRAPHIC="${TEST_INFOGRAPHICS_DIR}/test-aggregate.json") |
4301 | +add_definitions(-DTEST_ITERATE_INFOGRAPHIC="${TEST_INFOGRAPHICS_DIR}/test-iterate.json") |
4302 | + |
4303 | add_definitions(-DDATA_DIR="${DATA_DIR}") |
4304 | |
4305 | add_subdirectory(data) |
4306 | |
4307 | === added directory 'tests/data/infographics' |
4308 | === added file 'tests/data/infographics/test-aggregate.json' |
4309 | --- tests/data/infographics/test-aggregate.json 1970-01-01 00:00:00 +0000 |
4310 | +++ tests/data/infographics/test-aggregate.json 2014-04-03 13:02:15 +0000 |
4311 | @@ -0,0 +1,13 @@ |
4312 | +{ |
4313 | + "exec": "/bin/cat", |
4314 | + "type": "aggregate", |
4315 | + "input": { |
4316 | + "com.ubuntu.camera": [ |
4317 | + "camera-photos.libusermetrics.json", |
4318 | + "camera-videos.libusermetrics.json" |
4319 | + ], |
4320 | + "foo": [ |
4321 | + "source-id.libusermetrics.json" |
4322 | + ] |
4323 | + } |
4324 | +} |
4325 | \ No newline at end of file |
4326 | |
4327 | === added file 'tests/data/infographics/test-iterate.json' |
4328 | --- tests/data/infographics/test-iterate.json 1970-01-01 00:00:00 +0000 |
4329 | +++ tests/data/infographics/test-iterate.json 2014-04-03 13:02:15 +0000 |
4330 | @@ -0,0 +1,9 @@ |
4331 | +{ |
4332 | + "exec": "/bin/echo", |
4333 | + "type": "iterate", |
4334 | + "input": { |
4335 | + "*": [ |
4336 | + ".*.libusermetrics.json" |
4337 | + ] |
4338 | + } |
4339 | +} |
4340 | |
4341 | === modified file 'tests/data/valgrind.suppression' |
4342 | --- tests/data/valgrind.suppression 2014-01-03 15:51:12 +0000 |
4343 | +++ tests/data/valgrind.suppression 2014-04-03 13:02:15 +0000 |
4344 | @@ -61,6 +61,25 @@ |
4345 | ################### |
4346 | |
4347 | { |
4348 | + QThread seems to leak here |
4349 | + Memcheck:Leak |
4350 | + match-leak-kinds: definite |
4351 | + fun:_Znwm |
4352 | + fun:_ZN14QThreadPrivateC1EP11QThreadData |
4353 | + fun:_ZN7QThreadC1EP7QObject |
4354 | +} |
4355 | + |
4356 | +{ |
4357 | + QThread seems to leak here |
4358 | + Memcheck:Leak |
4359 | + match-leak-kinds: definite |
4360 | + fun:_Znwj |
4361 | + fun:_ZN14QThreadPrivateC1EP11QThreadData |
4362 | + fun:_ZN7QThreadC1EP7QObject |
4363 | +} |
4364 | + |
4365 | + |
4366 | +{ |
4367 | See bug report <https://bugreports.qt-project.org/browse/QTBUG-33677> |
4368 | Memcheck:Leak |
4369 | fun:_Znwm |
4370 | |
4371 | === modified file 'tests/unit/libusermetricsinput/TestMetricImpl.cpp' |
4372 | --- tests/unit/libusermetricsinput/TestMetricImpl.cpp 2014-01-06 13:24:12 +0000 |
4373 | +++ tests/unit/libusermetricsinput/TestMetricImpl.cpp 2014-04-03 13:02:15 +0000 |
4374 | @@ -70,7 +70,7 @@ |
4375 | |
4376 | QVariantMap readData(const QString &id) { |
4377 | QVariantMap map; |
4378 | - QFile file(metricDir.filePath(id + ".json")); |
4379 | + QFile file(metricDir.filePath(id + ".libusermetrics.json")); |
4380 | EXPECT_TRUE(file.open(QIODevice::ReadOnly)); |
4381 | QJsonDocument doc(QJsonDocument::fromJson(file.readAll())); |
4382 | file.close(); |
4383 | |
4384 | === modified file 'tests/unit/libusermetricsinput/TestMetricManagerImpl.cpp' |
4385 | --- tests/unit/libusermetricsinput/TestMetricManagerImpl.cpp 2014-01-06 17:31:49 +0000 |
4386 | +++ tests/unit/libusermetricsinput/TestMetricManagerImpl.cpp 2014-04-03 13:02:15 +0000 |
4387 | @@ -21,6 +21,7 @@ |
4388 | #include <testutils/QStringPrinter.h> |
4389 | #include <unit/libusermetricsinput/Mocks.h> |
4390 | |
4391 | +#include <QtCore/QDebug> |
4392 | #include <QtCore/QTemporaryDir> |
4393 | |
4394 | #include <gtest/gtest.h> |
4395 | @@ -49,6 +50,7 @@ |
4396 | "usermetrics"); |
4397 | |
4398 | applicationIdTwo = "app-id-2"; |
4399 | + applicationIdTwoFull = "app-id-2_app_1.2.12345"; |
4400 | metricDirTwo = QDir(cacheDir.filePath(applicationIdTwo)).filePath( |
4401 | "usermetrics"); |
4402 | } |
4403 | @@ -77,6 +79,8 @@ |
4404 | |
4405 | QString applicationIdTwo; |
4406 | |
4407 | + QString applicationIdTwoFull; |
4408 | + |
4409 | QDir metricDirTwo; |
4410 | }; |
4411 | |
4412 | @@ -85,8 +89,7 @@ |
4413 | params.formatString("format string %1"); |
4414 | |
4415 | MetricManagerPtr manager( |
4416 | - new MetricManagerImpl(factory, temporaryDir.path(), |
4417 | - applicationIdOne)); |
4418 | + new MetricManagerImpl(factory, cacheDir, applicationIdOne)); |
4419 | EXPECT_CALL(*factory, newMetric(metricDirOne, |
4420 | params, _)).WillOnce(Return(metric)); |
4421 | MetricPtr newMetric(manager->add(params)); |
4422 | @@ -95,9 +98,9 @@ |
4423 | newMetric = manager->add(params); |
4424 | EXPECT_EQ(metric, newMetric); |
4425 | |
4426 | - EXPECT_DIR_CONTAINS(QDir(cacheDir.filePath(applicationIdOne)), |
4427 | + EXPECT_DIR_CONTAINS(cacheDir, QStringList() << applicationIdOne); |
4428 | + EXPECT_DIR_CONTAINS(cacheDir.filePath(applicationIdOne), |
4429 | QStringList() << "usermetrics"); |
4430 | - EXPECT_DIR_CONTAINS(cacheDir, QStringList() << applicationIdOne); |
4431 | } |
4432 | |
4433 | TEST_F(TestMetricManagerImpl, CreateTwoDifferentApplications) { |
4434 | @@ -106,8 +109,7 @@ |
4435 | |
4436 | { |
4437 | MetricManagerPtr manager( |
4438 | - new MetricManagerImpl(factory, temporaryDir.path(), |
4439 | - applicationIdOne)); |
4440 | + new MetricManagerImpl(factory, cacheDir, applicationIdOne)); |
4441 | EXPECT_CALL(*factory, newMetric(metricDirOne, |
4442 | params, _)).WillOnce(Return(metric)); |
4443 | MetricPtr newMetric(manager->add(params)); |
4444 | @@ -116,18 +118,19 @@ |
4445 | |
4446 | { |
4447 | MetricManagerPtr manager( |
4448 | - new MetricManagerImpl(factory, temporaryDir.path(), |
4449 | - applicationIdTwo)); |
4450 | + new MetricManagerImpl(factory, cacheDir, applicationIdTwoFull)); |
4451 | EXPECT_CALL(*factory, newMetric(metricDirTwo, |
4452 | params, _)).WillOnce(Return(metric)); |
4453 | MetricPtr newMetric(manager->add("data-source-id", "format string %1")); |
4454 | EXPECT_EQ(metric, newMetric); |
4455 | } |
4456 | |
4457 | - EXPECT_DIR_CONTAINS(QDir(cacheDir.filePath(applicationIdTwo)), |
4458 | - QStringList() << "usermetrics"); |
4459 | EXPECT_DIR_CONTAINS(cacheDir, |
4460 | QStringList() << applicationIdOne << applicationIdTwo); |
4461 | + EXPECT_DIR_CONTAINS(cacheDir.filePath(applicationIdOne), |
4462 | + QStringList() << "usermetrics"); |
4463 | + EXPECT_DIR_CONTAINS(cacheDir.filePath(applicationIdTwo), |
4464 | + QStringList() << "usermetrics"); |
4465 | } |
4466 | |
4467 | TEST_F(TestMetricManagerImpl, TestCanAddDataSourceMultipleTimes) { |
4468 | @@ -154,9 +157,9 @@ |
4469 | EXPECT_EQ(metric, newMetric); |
4470 | } |
4471 | |
4472 | - EXPECT_DIR_CONTAINS(QDir(cacheDir.filePath(applicationIdOne)), |
4473 | + EXPECT_DIR_CONTAINS(cacheDir, QStringList() << applicationIdOne); |
4474 | + EXPECT_DIR_CONTAINS(cacheDir.filePath(applicationIdOne), |
4475 | QStringList() << "usermetrics"); |
4476 | - EXPECT_DIR_CONTAINS(cacheDir, QStringList() << applicationIdOne); |
4477 | } |
4478 | |
4479 | } // namespace |
4480 | |
4481 | === modified file 'tests/unit/libusermetricsinput/TestUserMetricInputCAPI.cpp' |
4482 | --- tests/unit/libusermetricsinput/TestUserMetricInputCAPI.cpp 2014-01-06 17:31:49 +0000 |
4483 | +++ tests/unit/libusermetricsinput/TestUserMetricInputCAPI.cpp 2014-04-03 13:02:15 +0000 |
4484 | @@ -48,9 +48,9 @@ |
4485 | QVariantMap readData(const QString &id) { |
4486 | QDir cacheDir(QDir(m_temporaryDir.path()).filePath(".cache")); |
4487 | QDir applicationDir(cacheDir.filePath("test-app")); |
4488 | - QDir metricDir(applicationDir.filePath("usermetrics")); |
4489 | + QDir usermetricsDir(applicationDir.filePath("usermetrics")); |
4490 | |
4491 | - QFile file(metricDir.filePath(id + ".json")); |
4492 | + QFile file(usermetricsDir.filePath(id + ".libusermetrics.json")); |
4493 | EXPECT_TRUE(file.open(QIODevice::ReadOnly)); |
4494 | QJsonDocument doc(QJsonDocument::fromJson(file.readAll())); |
4495 | file.close(); |
4496 | |
4497 | === modified file 'tests/unit/libusermetricsoutput/CMakeLists.txt' |
4498 | --- tests/unit/libusermetricsoutput/CMakeLists.txt 2014-01-03 11:40:22 +0000 |
4499 | +++ tests/unit/libusermetricsoutput/CMakeLists.txt 2014-04-03 13:02:15 +0000 |
4500 | @@ -5,6 +5,7 @@ |
4501 | TestColorThemeImpl.cpp |
4502 | TestDataSet.cpp |
4503 | TestGSettingsColorThemeProvider.cpp |
4504 | + TestInfographicListImpl.cpp |
4505 | TestQVariantListModel.cpp |
4506 | TestUserMetricsImpl.cpp |
4507 | ) |
4508 | |
4509 | === added file 'tests/unit/libusermetricsoutput/TestInfographicListImpl.cpp' |
4510 | --- tests/unit/libusermetricsoutput/TestInfographicListImpl.cpp 1970-01-01 00:00:00 +0000 |
4511 | +++ tests/unit/libusermetricsoutput/TestInfographicListImpl.cpp 2014-04-03 13:02:15 +0000 |
4512 | @@ -0,0 +1,122 @@ |
4513 | +/* |
4514 | + * Copyright (C) 2014 Canonical, Ltd. |
4515 | + * |
4516 | + * This program is free software; you can redistribute it and/or modify |
4517 | + * it under the terms of the GNU General Public License as published by |
4518 | + * the Free Software Foundation; version 3. |
4519 | + * |
4520 | + * This program is distributed in the hope that it will be useful, |
4521 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4522 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4523 | + * GNU General Public License for more details. |
4524 | + * |
4525 | + * You should have received a copy of the GNU General Public License |
4526 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4527 | + * |
4528 | + * Author: Pete Woods <pete.woods@canonical.com> |
4529 | + */ |
4530 | + |
4531 | +#include <libusermetricsoutput/InfographicListImpl.h> |
4532 | + |
4533 | +#include <QDebug> |
4534 | +#include <QSignalSpy> |
4535 | +#include <QTemporaryDir> |
4536 | + |
4537 | +#include <gtest/gtest.h> |
4538 | +#include <gmock/gmock.h> |
4539 | + |
4540 | +using namespace std; |
4541 | +using namespace UserMetricsOutput; |
4542 | +using namespace testing; |
4543 | + |
4544 | +namespace { |
4545 | + |
4546 | +class TestInfographicListImpl: public Test { |
4547 | +protected: |
4548 | + void SetUp() { |
4549 | + qRegisterMetaType<QVector<int>>("QVector<int>"); |
4550 | + usermetricsDir = tempDir.path(); |
4551 | + } |
4552 | + |
4553 | + QDir createUserDir(unsigned int uid) { |
4554 | + QString name(QString::number(uid)); |
4555 | + usermetricsDir.mkpath(name); |
4556 | + return QDir(usermetricsDir.filePath(name)); |
4557 | + } |
4558 | + |
4559 | + QString createInfographic(unsigned int uid, const QString &visualizer, |
4560 | + const QString &name, const QByteArray &contents) { |
4561 | + QDir userDir(createUserDir(uid)); |
4562 | + |
4563 | + userDir.mkpath(visualizer); |
4564 | + QDir visualizerDir(userDir.filePath(visualizer)); |
4565 | + |
4566 | + QFile output(visualizerDir.filePath(name)); |
4567 | + output.open(QIODevice::WriteOnly); |
4568 | + output.write(contents); |
4569 | + output.close(); |
4570 | + |
4571 | + return output.fileName(); |
4572 | + } |
4573 | + |
4574 | + QStringList contents(QAbstractItemModel &model) { |
4575 | + QStringList contents; |
4576 | + for (int i(0); i < model.rowCount(); ++i) { |
4577 | + contents << model.data(model.index(i, 0)).toString(); |
4578 | + } |
4579 | + contents.sort(); |
4580 | + return contents; |
4581 | + } |
4582 | + |
4583 | + QTemporaryDir tempDir; |
4584 | + |
4585 | + QDir usermetricsDir; |
4586 | +}; |
4587 | + |
4588 | +TEST_F(TestInfographicListImpl, ModelUpdated) { |
4589 | + InfographicListImpl list(tempDir.path()); |
4590 | + EXPECT_EQ(QStringList(), contents(list)); |
4591 | + |
4592 | + QSignalSpy resetSpy(&list, SIGNAL(modelReset())); |
4593 | + QSignalSpy dataChangedSpy(&list, |
4594 | + SIGNAL( |
4595 | + dataChanged(const QModelIndex &, const QModelIndex &, const QVector<int> &))); |
4596 | + |
4597 | + list.setUid(1234); |
4598 | + |
4599 | + createInfographic(1234, "com.ubuntu.camera", "apple-1234.svg", "<apple/>"); |
4600 | + QString appleFile = createInfographic(1234, "com.ubuntu.camera", |
4601 | + "apple-2345.svg", "<apple/>"); |
4602 | + |
4603 | + createInfographic(1234, "com.ubuntu.camera", "banana-1234.svg", |
4604 | + "<oldBanana/>"); |
4605 | + createInfographic(1234, "com.ubuntu.camera", "banana-2345.svg", |
4606 | + "<oldBanana/>"); |
4607 | + QString bananaFile = createInfographic(1234, "com.ubuntu.camera", |
4608 | + "banana-3456.svg", "<banana/>"); |
4609 | + |
4610 | + createInfographic(1234, "com.ubuntu.camera", "cherry-1234.svg", |
4611 | + "<oldCherry/>"); |
4612 | + createInfographic(1234, "com.ubuntu.camera", "cherry-2345.svg", |
4613 | + "<oldCherry/>"); |
4614 | + QString cherryFile = createInfographic(1234, "com.ubuntu.camera", |
4615 | + "cherry-3456.svg", "<cherry/>"); |
4616 | + |
4617 | + resetSpy.wait(); |
4618 | + ASSERT_EQ(1, resetSpy.size()); |
4619 | + resetSpy.clear(); |
4620 | + |
4621 | + EXPECT_EQ(QStringList() << appleFile << bananaFile << cherryFile, |
4622 | + contents(list)); |
4623 | + |
4624 | + QString fooFile = createInfographic(1234, "com.ubuntu.foo", "foo-1234.svg", |
4625 | + "<foo/>"); |
4626 | + |
4627 | + dataChangedSpy.wait(); |
4628 | + ASSERT_EQ(1, dataChangedSpy.size()); |
4629 | + |
4630 | + EXPECT_EQ(QStringList() << appleFile << bananaFile << cherryFile << fooFile, |
4631 | + contents(list)); |
4632 | +} |
4633 | + |
4634 | +} // namespace |
4635 | |
4636 | === modified file 'tests/unit/qml/UserMetricsTest/DBusQuery.cpp' |
4637 | --- tests/unit/qml/UserMetricsTest/DBusQuery.cpp 2014-01-06 17:31:49 +0000 |
4638 | +++ tests/unit/qml/UserMetricsTest/DBusQuery.cpp 2014-04-03 13:02:15 +0000 |
4639 | @@ -30,10 +30,10 @@ |
4640 | static QVariantMap fileContents(int index) { |
4641 | QDir cacheDir(TEST_CACHE_DIR); |
4642 | QDir applicationDir(cacheDir.filePath("test-app")); |
4643 | - QDir metricDir(applicationDir.filePath("usermetrics")); |
4644 | + QDir usermetricsDir(applicationDir.filePath("usermetrics")); |
4645 | |
4646 | QFileInfoList list( |
4647 | - metricDir.entryInfoList(QDir::Files | QDir::NoDotAndDotDot, |
4648 | + usermetricsDir.entryInfoList(QDir::Files | QDir::NoDotAndDotDot, |
4649 | QDir::Reversed)); |
4650 | if (index - 1 >= list.length()) { |
4651 | return QVariantMap(); |
4652 | |
4653 | === modified file 'tests/unit/qml/UserMetricsTest/TestPlugin.cpp' |
4654 | --- tests/unit/qml/UserMetricsTest/TestPlugin.cpp 2014-01-06 17:31:49 +0000 |
4655 | +++ tests/unit/qml/UserMetricsTest/TestPlugin.cpp 2014-04-03 13:02:15 +0000 |
4656 | @@ -28,8 +28,9 @@ |
4657 | void Components::initializeEngine(QQmlEngine *engine, const char *uri) { |
4658 | QDir cacheDir(TEST_CACHE_DIR); |
4659 | QDir applicationDir(cacheDir.filePath(qgetenv("APP_ID"))); |
4660 | - if (applicationDir.exists()) { |
4661 | - applicationDir.removeRecursively(); |
4662 | + QDir usermetricsDir(applicationDir.filePath("usermetrics")); |
4663 | + if (usermetricsDir.exists()) { |
4664 | + usermetricsDir.removeRecursively(); |
4665 | } |
4666 | |
4667 | m_dbusQuery.reset(new DBusQuery()); |
4668 | |
4669 | === modified file 'tests/unit/usermetricsservice/CMakeLists.txt' |
4670 | --- tests/unit/usermetricsservice/CMakeLists.txt 2014-01-03 11:40:22 +0000 |
4671 | +++ tests/unit/usermetricsservice/CMakeLists.txt 2014-04-03 13:02:15 +0000 |
4672 | @@ -0,0 +1,25 @@ |
4673 | + |
4674 | +set( |
4675 | + USERMETRICSSERVICE_UNIT_TESTS_SRC |
4676 | + TestServiceImpl.cpp |
4677 | + TestInfographicImpl.cpp |
4678 | +) |
4679 | + |
4680 | +add_executable( |
4681 | + usermetricsservice-unit-tests |
4682 | + ${USERMETRICSSERVICE_UNIT_TESTS_SRC} |
4683 | +) |
4684 | + |
4685 | +target_link_libraries( |
4686 | + usermetricsservice-unit-tests |
4687 | + usermetricsservice |
4688 | + usermetrics-test-utils |
4689 | + ${GSETTINGS_QT_LIBRARIES} |
4690 | + ${GTEST_LIBRARIES} |
4691 | + ${GMOCK_LIBRARIES} |
4692 | +) |
4693 | + |
4694 | +add_valgrind_test( |
4695 | + usermetricsservice-unit-tests |
4696 | + usermetricsservice-unit-tests |
4697 | +) |
4698 | |
4699 | === added file 'tests/unit/usermetricsservice/Mocks.h' |
4700 | --- tests/unit/usermetricsservice/Mocks.h 1970-01-01 00:00:00 +0000 |
4701 | +++ tests/unit/usermetricsservice/Mocks.h 2014-04-03 13:02:15 +0000 |
4702 | @@ -0,0 +1,84 @@ |
4703 | +/* |
4704 | + * Copyright (C) 2013 Canonical, Ltd. |
4705 | + * |
4706 | + * This program is free software: you can redistribute it and/or modify it |
4707 | + * under the terms of the GNU General Public License version 3, as published |
4708 | + * by the Free Software Foundation. |
4709 | + * |
4710 | + * This program is distributed in the hope that it will be useful, but |
4711 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
4712 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
4713 | + * PURPOSE. See the GNU General Public License for more details. |
4714 | + * |
4715 | + * You should have received a copy of the GNU General Public License along |
4716 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
4717 | + * |
4718 | + * Author: Pete Woods <pete.woods@canonical.com> |
4719 | + */ |
4720 | + |
4721 | +#ifndef USERMETRICSSERVICE_TEST_MOCKS_H_ |
4722 | +#define USERMETRICSSERVICE_TEST_MOCKS_H_ |
4723 | + |
4724 | +#include <usermetricsservice/Factory.h> |
4725 | + |
4726 | +#include <gmock/gmock.h> |
4727 | + |
4728 | +namespace UserMetricsService { |
4729 | +namespace Mocks { |
4730 | + |
4731 | +class MockFactory: public Factory { |
4732 | +public: |
4733 | + |
4734 | + MOCK_METHOD0(singletonService, Service::Ptr()); |
4735 | + |
4736 | + MOCK_METHOD0(singletonFileUtils, UserMetricsCommon::FileUtils::Ptr()); |
4737 | + |
4738 | + MOCK_METHOD0(singletonExecutor, Executor::Ptr()); |
4739 | + |
4740 | + MOCK_METHOD0(singletonInfographicService, QSharedPointer<ComCanonicalInfographicsInterface>()); |
4741 | + |
4742 | + MOCK_METHOD0(singletonResultTransport, ResultTransport::Ptr()); |
4743 | + |
4744 | + MOCK_METHOD1(newInfographic, Infographic::Ptr(const QFile &)); |
4745 | + |
4746 | + MOCK_METHOD1(newSourceDirectory, SourceDirectory::Ptr(const QDir &)); |
4747 | +}; |
4748 | + |
4749 | +class MockExecutor: public Executor { |
4750 | +public: |
4751 | + |
4752 | + MOCK_METHOD2(execute, QByteArray(const QString &, |
4753 | + const QStringList &)); |
4754 | +}; |
4755 | + |
4756 | +class MockInfographic: public Infographic { |
4757 | +public: |
4758 | + |
4759 | + MOCK_CONST_METHOD0(isValid, bool()); |
4760 | + |
4761 | + MOCK_CONST_METHOD0(type, Infographic::Type()); |
4762 | + |
4763 | + MOCK_METHOD2(sourcesChanged, void(const QMultiMap<QString, QString> &, |
4764 | + const QMultiMap<QString, QString> &)); |
4765 | +}; |
4766 | + |
4767 | +class MockFileUtils: public UserMetricsCommon::FileUtils { |
4768 | +public: |
4769 | + |
4770 | + MOCK_METHOD2(listDirectory, QSet<QString>(const QDir &, |
4771 | + QDir::Filters)); |
4772 | +}; |
4773 | + |
4774 | +class MockResultTransport: public ResultTransport { |
4775 | +public: |
4776 | + |
4777 | + MOCK_METHOD0(clear, void()); |
4778 | + |
4779 | + MOCK_METHOD3(send, void(const QString &, const QStringList &, |
4780 | + const QByteArray &)); |
4781 | +}; |
4782 | + |
4783 | +} |
4784 | +} |
4785 | + |
4786 | +#endif /* USERMETRICSSERVICE_TEST_MOCKS_H_ */ |
4787 | |
4788 | === added file 'tests/unit/usermetricsservice/TestInfographicImpl.cpp' |
4789 | --- tests/unit/usermetricsservice/TestInfographicImpl.cpp 1970-01-01 00:00:00 +0000 |
4790 | +++ tests/unit/usermetricsservice/TestInfographicImpl.cpp 2014-04-03 13:02:15 +0000 |
4791 | @@ -0,0 +1,124 @@ |
4792 | +/* |
4793 | + * Copyright (C) 2013 Canonical, Ltd. |
4794 | + * |
4795 | + * This program is free software; you can redistribute it and/or modify |
4796 | + * it under the terms of the GNU General Public License as published by |
4797 | + * the Free Software Foundation; version 3. |
4798 | + * |
4799 | + * This program is distributed in the hope that it will be useful, |
4800 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4801 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4802 | + * GNU General Public License for more details. |
4803 | + * |
4804 | + * You should have received a copy of the GNU General Public License |
4805 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4806 | + * |
4807 | + * Author: Pete Woods <pete.woods@canonical.com> |
4808 | + */ |
4809 | + |
4810 | +#include <stdexcept> |
4811 | + |
4812 | +#include <usermetricsservice/InfographicImpl.h> |
4813 | + |
4814 | +#include <unit/usermetricsservice/Mocks.h> |
4815 | +#include <testutils/QStringPrinter.h> |
4816 | + |
4817 | +#include <gtest/gtest.h> |
4818 | +#include <gmock/gmock.h> |
4819 | + |
4820 | +using namespace std; |
4821 | +using namespace testing; |
4822 | +using namespace UserMetricsService; |
4823 | +using namespace UserMetricsService::Mocks; |
4824 | + |
4825 | +namespace { |
4826 | + |
4827 | +class TestInfographicImpl: public Test { |
4828 | +protected: |
4829 | + void SetUp() { |
4830 | + executor.reset(new StrictMock<MockExecutor>); |
4831 | + |
4832 | + resultTransport.reset(new StrictMock<MockResultTransport>); |
4833 | + } |
4834 | + |
4835 | + QSharedPointer<MockExecutor> executor; |
4836 | + |
4837 | + QSharedPointer<MockResultTransport> resultTransport; |
4838 | + |
4839 | + Infographic::Ptr newInfographic(const QString &path) { |
4840 | + return Infographic::Ptr( |
4841 | + new InfographicImpl(path, executor, resultTransport)); |
4842 | + } |
4843 | +}; |
4844 | + |
4845 | +TEST_F(TestInfographicImpl, Iterate) { |
4846 | + Infographic::Ptr infographic(newInfographic (TEST_ITERATE_INFOGRAPHIC)); |
4847 | + |
4848 | + EXPECT_TRUE(infographic->isValid()); |
4849 | + EXPECT_EQ(Infographic::Type::ITERATE, infographic->type()); |
4850 | + |
4851 | + QMultiMap<QString, QString> changedSources; |
4852 | + changedSources.insert("apple", "/path/orchard.libusermetrics.json"); |
4853 | + changedSources.insert("apple", "/path/grove.json"); |
4854 | + changedSources.insert("banana", "/path/tree.libusermetrics.json"); |
4855 | + |
4856 | + QMultiMap<QString, QString> allSources; |
4857 | + |
4858 | + QByteArray orchardBa("orchard"); |
4859 | + QStringList orchard; |
4860 | + orchard << "/path/orchard.libusermetrics.json"; |
4861 | + EXPECT_CALL(*executor, |
4862 | + execute(QString("/bin/echo"), orchard)).WillOnce(Return(orchardBa)); |
4863 | + EXPECT_CALL(*resultTransport, |
4864 | + send(QString("test-iterate"), orchard, orchardBa)); |
4865 | + |
4866 | + QByteArray treeBa("tree blah"); |
4867 | + QStringList tree; |
4868 | + tree << "/path/tree.libusermetrics.json"; |
4869 | + EXPECT_CALL(*executor, |
4870 | + execute(QString("/bin/echo"), tree)).WillOnce(Return(treeBa)); |
4871 | + EXPECT_CALL(*resultTransport, send(QString("test-iterate"), tree, treeBa)); |
4872 | + |
4873 | + infographic->sourcesChanged(changedSources, allSources); |
4874 | +} |
4875 | + |
4876 | +TEST_F(TestInfographicImpl, Aggregate) { |
4877 | + Infographic::Ptr infographic(newInfographic (TEST_AGGREGATE_INFOGRAPHIC)); |
4878 | + |
4879 | + EXPECT_TRUE(infographic->isValid()); |
4880 | + EXPECT_EQ(Infographic::Type::AGGREGATE, infographic->type()); |
4881 | + |
4882 | + QMultiMap<QString, QString> changedSources; |
4883 | + QMultiMap<QString, QString> allSources; |
4884 | + |
4885 | + // Only two of the 3 requires sources are present |
4886 | + allSources.insert("foo", "/path/source-1.libusermetrics.json"); |
4887 | + allSources.insert("foo", "/path/source-2.libusermetrics.json"); |
4888 | + allSources.insert("com.ubuntu.camera", |
4889 | + "/path/camera-photos.libusermetrics.json"); |
4890 | + allSources.insert("com.ubuntu.camera", |
4891 | + "/path/camera-videos.libusermetrics.json"); |
4892 | + allSources.insert("bar", "/path/bar.libusermetrics.json"); |
4893 | + |
4894 | + changedSources.insert("com.ubuntu.camera", |
4895 | + "/path/camera-videos.libusermetrics.json"); |
4896 | + |
4897 | + // Nothing should happen |
4898 | + infographic->sourcesChanged(changedSources, allSources); |
4899 | + |
4900 | + // Now all of the required sources are present |
4901 | + allSources.insert("foo", "/path/source-id.libusermetrics.json"); |
4902 | + |
4903 | + QByteArray ba("stuff in the byte array"); |
4904 | + QStringList files; |
4905 | + files << "/path/camera-photos.libusermetrics.json" |
4906 | + << "/path/camera-videos.libusermetrics.json" |
4907 | + << "/path/source-id.libusermetrics.json"; |
4908 | + EXPECT_CALL(*executor, |
4909 | + execute(QString("/bin/cat"), files)).WillOnce(Return(ba)); |
4910 | + EXPECT_CALL(*resultTransport, send(QString("test-aggregate"), files, ba)); |
4911 | + |
4912 | + infographic->sourcesChanged(changedSources, allSources); |
4913 | +} |
4914 | + |
4915 | +} // namespace |
4916 | |
4917 | === added file 'tests/unit/usermetricsservice/TestServiceImpl.cpp' |
4918 | --- tests/unit/usermetricsservice/TestServiceImpl.cpp 1970-01-01 00:00:00 +0000 |
4919 | +++ tests/unit/usermetricsservice/TestServiceImpl.cpp 2014-04-03 13:02:15 +0000 |
4920 | @@ -0,0 +1,149 @@ |
4921 | +/* |
4922 | + * Copyright (C) 2013 Canonical, Ltd. |
4923 | + * |
4924 | + * This program is free software; you can redistribute it and/or modify |
4925 | + * it under the terms of the GNU General Public License as published by |
4926 | + * the Free Software Foundation; version 3. |
4927 | + * |
4928 | + * This program is distributed in the hope that it will be useful, |
4929 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
4930 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4931 | + * GNU General Public License for more details. |
4932 | + * |
4933 | + * You should have received a copy of the GNU General Public License |
4934 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
4935 | + * |
4936 | + * Author: Pete Woods <pete.woods@canonical.com> |
4937 | + */ |
4938 | + |
4939 | +#include <usermetricsservice/ServiceImpl.h> |
4940 | +#include <usermetricsservice/SourceDirectoryImpl.h> |
4941 | +#include <unit/usermetricsservice/Mocks.h> |
4942 | +#include <testutils/QStringPrinter.h> |
4943 | + |
4944 | +#include <QSignalSpy> |
4945 | +#include <QTemporaryDir> |
4946 | +#include <gtest/gtest.h> |
4947 | +#include <gmock/gmock.h> |
4948 | +#include <stdexcept> |
4949 | + |
4950 | +using namespace std; |
4951 | +using namespace testing; |
4952 | +using namespace UserMetricsCommon; |
4953 | +using namespace UserMetricsService; |
4954 | +using namespace UserMetricsService::Mocks; |
4955 | + |
4956 | +MATCHER_P(HasPath, value, ""){ return arg.fileName() == value;} |
4957 | + |
4958 | +namespace { |
4959 | + |
4960 | +class TestServiceImpl: public Test { |
4961 | +protected: |
4962 | + void SetUp() { |
4963 | + qRegisterMetaType<QMultiMap<QString, QString>>( |
4964 | + "QMultiMap<QString, QString>"); |
4965 | + |
4966 | + cacheDir = tempDir.path(); |
4967 | + usermetricsDir = cacheDir.filePath("usermetrics"); |
4968 | + sourcesDir = usermetricsDir.filePath("sources"); |
4969 | + ASSERT_TRUE(usermetricsDir.mkpath("sources")); |
4970 | + |
4971 | + factory.reset(new NiceMock<MockFactory>); |
4972 | + fileUtils.reset(new FileUtils); |
4973 | + resultTransport.reset(new StrictMock<MockResultTransport>); |
4974 | + } |
4975 | + |
4976 | + Service::Ptr newService() { |
4977 | + return Service::Ptr( |
4978 | + new ServiceImpl(cacheDir.path(), QDir(TEST_INFOGRAPHICS_DIR), |
4979 | + fileUtils, resultTransport, *factory)); |
4980 | + } |
4981 | + |
4982 | + QDir applicationDir(const QString &sourceName) { |
4983 | + QDir applicationDir = cacheDir.filePath(sourceName); |
4984 | + return applicationDir.filePath("usermetrics"); |
4985 | + } |
4986 | + |
4987 | + void createSource(const QString &name) { |
4988 | + QFile source(sourcesDir.filePath(name)); |
4989 | + ASSERT_TRUE(source.open(QIODevice::WriteOnly)); |
4990 | + ASSERT_TRUE(source.write("blah")); |
4991 | + source.close(); |
4992 | + } |
4993 | + |
4994 | + QString metricPath(const QString &sourceName, const QString &metricName) { |
4995 | + QDir applicationDir = cacheDir.filePath(sourceName); |
4996 | + QDir applicationUsermetricsDir = applicationDir.filePath("usermetrics"); |
4997 | + return applicationUsermetricsDir.filePath(metricName); |
4998 | + } |
4999 | + |
5000 | + void createMetric(const QString &sourceName, const QString &metricName) { |
Hey, this is looking good, I'll try and skim through this for a code review, but I've a few comments looking at the API:
- there's no reason for the separate infographics property, just make InfographicsList a QAbstractListModel (any reason for using *ItemModel instead, btw?) with just a "source" role
- as discussed on IRC, the filesUpdated() signal feels like a dirty API, I'd rather see timestamped file names and dataChanged on the "source" role when applicable; ideally both files would be available at the same time for a while (old files periodically garbage collected, basically?), in case we're still loading the old file while a new one got added
- the timeout logic feels unnecessary, we'll only be loading a single file (two at most during transitions); throttling should probably happen on the visualizer side, though?
- should we be (are we?) running the visualizers whenever data changes, or only when greeter is shown? on one hand that would mean they're ready when greeter is shown, on the other they might never be shown at all (in case user never switches between images)
BTW, what's the plan for i18n? Are we ok with the SVGs only updating the language on next update, or should we maybe kick the visualisers on locale change?