Merge lp:~unity-team/libusermetrics/file-based-infographics into lp:libusermetrics

Proposed by Pete Woods on 2014-04-03
Status: Approved
Approved by: Antti Kaijanmäki on 2014-08-06
Approved revision: 182
Proposed branch: lp:~unity-team/libusermetrics/file-based-infographics
Merge into: lp:libusermetrics
Diff against target: 14066 lines (+6354/-5861)
162 files modified
CMakeLists.txt (+6/-13)
cmake/FindValgrind.cmake (+1/-1)
cmake/Plugins.cmake (+102/-0)
data/CMakeLists.txt (+37/-10)
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/com.canonical.UserMetrics.service.in (+0/-5)
data/com.canonical.UserMetrics.xml (+0/-44)
data/com.canonical.usermetrics.DataSet.xml (+0/-24)
data/com.canonical.usermetrics.DataSource.xml (+0/-42)
data/com.canonical.usermetrics.UserData.xml (+0/-25)
data/default.json.in (+9/-0)
data/usermetricsservice.conf.in (+10/-0)
debian/changelog (+7/-0)
debian/control (+18/-7)
debian/libusermetricsinput1.symbols (+19/-8)
debian/libusermetricsoutput1.symbols (+18/-0)
debian/qtdeclarative5-infographics0.1.install (+1/-0)
debian/rules (+6/-2)
debian/usermetricsservice.infographic.click-hook (+3/-0)
debian/usermetricsservice.install (+1/-0)
debian/usermetricsservice.postinst (+0/-16)
debian/usermetricsservice.postrm (+0/-26)
debian/usermetricsservice.preinst (+0/-30)
debian/usermetricsservice.prerm (+0/-7)
debian/usermetricsservice.usermetrics.click-hook (+3/-0)
doc/Infographic Architecture.svg (+636/-0)
doc/mainpage.md (+87/-0)
po/en_GB.po (+88/-120)
po/libusermetrics.pot (+18/-108)
po/pl.po (+92/-121)
po/zh_CN.po (+28/-117)
src/CMakeLists.txt (+2/-0)
src/infographic/CMakeLists.txt (+20/-0)
src/infographic/Infographic.cpp (+292/-0)
src/infographic/Infographic.h (+79/-0)
src/infographic/main.cpp (+53/-0)
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 (+7/-29)
src/libusermetricscommon/DBusPaths.cpp (+0/-41)
src/libusermetricscommon/DBusPaths.h (+0/-41)
src/libusermetricscommon/FileUtils.cpp (+52/-0)
src/libusermetricscommon/FileUtils.h (+47/-0)
src/libusermetricsinput/CMakeLists.txt (+2/-0)
src/libusermetricsinput/Factory.cpp (+48/-0)
src/libusermetricsinput/Factory.h (+47/-0)
src/libusermetricsinput/Metric.h (+1/-1)
src/libusermetricsinput/MetricImpl.cpp (+228/-75)
src/libusermetricsinput/MetricImpl.h (+43/-20)
src/libusermetricsinput/MetricManager.cpp (+7/-13)
src/libusermetricsinput/MetricManager.h (+9/-23)
src/libusermetricsinput/MetricManagerImpl.cpp (+40/-93)
src/libusermetricsinput/MetricManagerImpl.h (+6/-4)
src/libusermetricsinput/MetricParameters.cpp (+132/-0)
src/libusermetricsinput/MetricParameters.h (+74/-0)
src/libusermetricsinput/MetricUpdate.h (+1/-1)
src/libusermetricsinput/MetricUpdateImpl.cpp (+6/-13)
src/libusermetricsinput/MetricUpdateImpl.h (+5/-8)
src/libusermetricsinput/usermetricsinput.cpp (+9/-8)
src/libusermetricsoutput/CMakeLists.txt (+3/-4)
src/libusermetricsoutput/ColorThemeProvider.h (+1/-0)
src/libusermetricsoutput/DirectoryWatcher.cpp (+118/-0)
src/libusermetricsoutput/DirectoryWatcher.h (+69/-0)
src/libusermetricsoutput/InfographicList.cpp (+32/-0)
src/libusermetricsoutput/InfographicList.h (+127/-0)
src/libusermetricsoutput/InfographicListImpl.cpp (+181/-0)
src/libusermetricsoutput/InfographicListImpl.h (+98/-0)
src/libusermetricsoutput/SyncedDataSet.cpp (+0/-34)
src/libusermetricsoutput/SyncedDataSet.h (+0/-43)
src/libusermetricsoutput/SyncedDataSource.cpp (+0/-54)
src/libusermetricsoutput/SyncedDataSource.h (+0/-46)
src/libusermetricsoutput/SyncedUserData.cpp (+0/-89)
src/libusermetricsoutput/SyncedUserData.h (+0/-56)
src/libusermetricsoutput/SyncedUserMetricsStore.cpp (+0/-142)
src/libusermetricsoutput/SyncedUserMetricsStore.h (+0/-63)
src/libusermetricsoutput/UserMetrics.cpp (+4/-9)
src/libusermetricsoutput/UserMetricsImpl.cpp (+6/-5)
src/libusermetricsoutput/UserMetricsStore.h (+2/-0)
src/modules/CMakeLists.txt (+1/-0)
src/modules/Infographics/CMakeLists.txt (+39/-0)
src/modules/Infographics/Components.cpp (+34/-0)
src/modules/Infographics/Components.h (+34/-0)
src/modules/Infographics/qmldir (+2/-0)
src/modules/UserMetrics/CMakeLists.txt (+27/-34)
src/usermetricsservice/Authentication.cpp (+0/-104)
src/usermetricsservice/Authentication.h (+0/-54)
src/usermetricsservice/CMakeLists.txt (+42/-53)
src/usermetricsservice/DBusDataSet.cpp (+0/-221)
src/usermetricsservice/DBusDataSet.h (+0/-100)
src/usermetricsservice/DBusDataSource.cpp (+0/-244)
src/usermetricsservice/DBusDataSource.h (+0/-115)
src/usermetricsservice/DBusUserData.cpp (+0/-186)
src/usermetricsservice/DBusUserData.h (+0/-95)
src/usermetricsservice/DBusUserMetrics.cpp (+0/-291)
src/usermetricsservice/DBusUserMetrics.h (+0/-90)
src/usermetricsservice/Executor.cpp (+27/-0)
src/usermetricsservice/Executor.h (+42/-0)
src/usermetricsservice/Factory.cpp (+91/-0)
src/usermetricsservice/Factory.h (+69/-0)
src/usermetricsservice/Infographic.cpp (+27/-0)
src/usermetricsservice/Infographic.h (+52/-0)
src/usermetricsservice/InfographicImpl.cpp (+180/-0)
src/usermetricsservice/InfographicImpl.h (+81/-0)
src/usermetricsservice/QProcessExecutor.cpp (+75/-0)
src/usermetricsservice/QProcessExecutor.h (+47/-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 (+172/-0)
src/usermetricsservice/ServiceImpl.h (+87/-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 (+56/-0)
src/usermetricsservice/database/DataSet.cpp (+0/-83)
src/usermetricsservice/database/DataSet.h (+0/-93)
src/usermetricsservice/database/DataSource.cpp (+0/-142)
src/usermetricsservice/database/DataSource.h (+0/-139)
src/usermetricsservice/database/UserData.cpp (+0/-56)
src/usermetricsservice/database/UserData.h (+0/-61)
src/usermetricsservice/main.cpp (+12/-63)
tests/CMakeLists.txt (+4/-1)
tests/data/infographics/test-aggregate.json (+13/-0)
tests/data/infographics/test-iterate.json (+9/-0)
tests/data/valgrind.suppression (+94/-0)
tests/integration/CMakeLists.txt (+0/-2)
tests/integration/libusermetricsinput/CMakeLists.txt (+0/-23)
tests/integration/libusermetricsinput/TestMetricManager.cpp (+0/-52)
tests/integration/libusermetricsoutput/CMakeLists.txt (+0/-23)
tests/integration/libusermetricsoutput/TestUserMetrics.cpp (+0/-46)
tests/testutils/CMakeLists.txt (+0/-2)
tests/testutils/DBusTest.cpp (+0/-50)
tests/testutils/DBusTest.h (+0/-49)
tests/testutils/main.cpp (+1/-1)
tests/unit/libusermetricsinput/CMakeLists.txt (+1/-0)
tests/unit/libusermetricsinput/Mocks.h (+51/-0)
tests/unit/libusermetricsinput/TestMetricImpl.cpp (+412/-0)
tests/unit/libusermetricsinput/TestMetricManagerImpl.cpp (+127/-322)
tests/unit/libusermetricsinput/TestUserMetricInputCAPI.cpp (+57/-57)
tests/unit/libusermetricsoutput/CMakeLists.txt (+1/-1)
tests/unit/libusermetricsoutput/TestInfographicListImpl.cpp (+121/-0)
tests/unit/libusermetricsoutput/TestSyncedUserMetricsStore.cpp (+0/-426)
tests/unit/qml/CMakeLists.txt (+9/-1)
tests/unit/qml/UserMetricsTest/DBusQuery.cpp (+42/-47)
tests/unit/qml/UserMetricsTest/DBusQuery.h (+0/-4)
tests/unit/qml/UserMetricsTest/TestPlugin.cpp (+7/-0)
tests/unit/qml/tst_Metrics.qml (+13/-2)
tests/unit/usermetricsservice/CMakeLists.txt (+3/-3)
tests/unit/usermetricsservice/Mocks.h (+84/-0)
tests/unit/usermetricsservice/TestAuthentication.cpp (+0/-62)
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/file-based-infographics
Reviewer Review Type Date Requested Status
Antti Kaijanmäki (community) Approve on 2014-08-06
Michał Sawicz 2014-04-03 Needs Information on 2014-07-10
PS Jenkins bot (community) continuous-integration Approve on 2014-06-25
Review via email: mp+214020@code.launchpad.net

Commit message

Wait until the Unity8 branch for the UI is ready

Description of the change

Wait until the Unity8 branch for the UI is ready

To post a comment you must log in.
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
152. By Pete Woods on 2014-04-03

Merge trunk

PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
153. By Pete Woods on 2014-04-04

Fix symbols file

154. By Pete Woods on 2014-04-07

Add new plug-in for unity8 shell to use

155. By Pete Woods on 2014-04-07

Use the correct subdirectory

156. By Pete Woods on 2014-04-07

Linewrap the control file

PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
157. By Pete Woods on 2014-04-07

Use Qt5 by default

PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
158. By Pete Woods on 2014-04-07

Add missing dependency

159. By Pete Woods on 2014-04-09

Avoid using new style connect method to (hopefully) fix test failures on ppc64 and arm64

PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
160. By Pete Woods on 2014-04-09

I forgot the parameters to the signals

161. By Pete Woods on 2014-04-09

Enable -fPIE for all executables

162. By Ricardo Salveti on 2014-04-14

Merging trunk

163. By Pete Woods on 2014-05-06

Additional documentation

164. By Pete Woods on 2014-05-08

Start on dbus started, like everyone else

165. By Pete Woods on 2014-05-08

Clean up the QML plugin

166. By Pete Woods on 2014-05-15

Derive the infographic confinement profile from the application ID

167. By Pete Woods on 2014-05-15

Remove needless logging

168. By Pete Woods on 2014-05-15

Move hook paths to ~/.local instead of ~/.cache

PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
169. By Pete Woods on 2014-05-15

Add data get method to help UI developers

PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
170. By Pete Woods on 2014-05-15

Merge trunk

171. By Pete Woods on 2014-05-22

Change output API to expose simple "path" property with "next" method

PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
172. By Pete Woods on 2014-05-22

Make jenkins happy with its non-optimised builds

173. By Pete Woods on 2014-05-22

Consistent formatting

PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
174. By Pete Woods on 2014-05-22

Make ARM builds on Jenkins happy

PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
175. By Pete Woods on 2014-05-28

Merge trunk

176. By Pete Woods on 2014-06-23

Merge trunk

177. By Pete Woods on 2014-06-23

Updated translations

178. By Pete Woods on 2014-06-23

Support sources provided by normal debian packages

179. By Pete Woods on 2014-06-23

Add package directories

180. By Pete Woods on 2014-06-23

Handle relative executable paths

181. By Pete Woods on 2014-06-23

Extra suppression

182. By Pete Woods on 2014-06-25

Extra method to specify APP_ID manually for non-UAL processes

Michał Sawicz (saviq) wrote :

Check out bug #1339002, seems to still happen - I disabled "stats on welcome screen" and locked, but they are still shown (even after reboot).

Not sure if the visualizer is here, but a few bugs for it:
- text not centered in the circle
- text is not pluralized correctly ("1 calls made today")

I wonder, (how) do we deal with language changes? I changed my display language, rebooted and infographics are still in English. Not sure if it's missing translations, or whether you're reacting to changed language at all?

review: Needs Information
Pete Woods (pete-woods) wrote :

> Check out bug #1339002, seems to still happen - I disabled "stats on welcome
> screen" and locked, but they are still shown (even after reboot).
>
I think unity8 was doing this with the old infographics implementation. Is it possible for me to read a user's settings as the lightdm user? Does unity8 know about this setting already for the user that's being displayed in the greeter?

> Not sure if the visualizer is here, but a few bugs for it:
> - text not centered in the circle
I will have a go at fixing this. SVGs have no concept of vertical centering, so it's hard.

> - text is not pluralized correctly ("1 calls made today")
This is because gettext doesn't support non-whole numbers, and the value is a double. e.g. for uses like "walked 1.1 km today".

> I wonder, (how) do we deal with language changes? I changed my display
> language, rebooted and infographics are still in English. Not sure if it's
> missing translations, or whether you're reacting to changed language at all?
The data source can either provide pre-translated strings (non optimal) or provide gettext translations under a specified domain. I don't think the apps are doing this at present.

All visualisers are basically re-run at user session start.

For custom visualisers that do completely their own wacky thing, it's up to the visualiser to be translatable.

Antti Kaijanmäki (kaijanmaki) wrote :

Had a review session with pete. LGTM.

review: Approve

Unmerged revisions

182. By Pete Woods on 2014-06-25

Extra method to specify APP_ID manually for non-UAL processes

181. By Pete Woods on 2014-06-23

Extra suppression

180. By Pete Woods on 2014-06-23

Handle relative executable paths

179. By Pete Woods on 2014-06-23

Add package directories

178. By Pete Woods on 2014-06-23

Support sources provided by normal debian packages

177. By Pete Woods on 2014-06-23

Updated translations

176. By Pete Woods on 2014-06-23

Merge trunk

175. By Pete Woods on 2014-05-28

Merge trunk

174. By Pete Woods on 2014-05-22

Make ARM builds on Jenkins happy

173. By Pete Woods on 2014-05-22

Consistent formatting

Preview Diff

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

Subscribers

People subscribed via source and target branches

to all changes: