cutedriver-driver 2.0.0.20210120164037

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (226) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +16 -0
  3. data/bin/start_app_perf +200 -0
  4. data/bin/tdriver-devtools +3 -0
  5. data/config/sut_parameters.rb +52 -0
  6. data/config/sut_setup.rb +32 -0
  7. data/config/sut_teardown.rb +32 -0
  8. data/config/tdriver_custom_error_recovery.rb +83 -0
  9. data/ext/extconf.rb +70 -0
  10. data/ext/native_extensions.c +315 -0
  11. data/lib/matti.rb +25 -0
  12. data/lib/tdriver-devtools/behaviour/old/xml/example/flick-example.rb +120 -0
  13. data/lib/tdriver-devtools/behaviour/old/xml/example/impl.rb_invalid +194 -0
  14. data/lib/tdriver-devtools/behaviour/old/xml/generate_behaviour_xml.rb +95 -0
  15. data/lib/tdriver-devtools/behaviour/old/xml/lib/tdriver_generator.rb +722 -0
  16. data/lib/tdriver-devtools/behaviour/old/xml/qdoc_generator.rb +321 -0
  17. data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.method.template +43 -0
  18. data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.module.template +54 -0
  19. data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.xml.argument.template +7 -0
  20. data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.xml.argument_type.template +7 -0
  21. data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.xml.exception.template +5 -0
  22. data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.xml.howto.line.template +2 -0
  23. data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.xml.howto.template +5 -0
  24. data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.xml.method.template +23 -0
  25. data/lib/tdriver-devtools/behaviour/old/xml/templates/behaviour.xml.template +14 -0
  26. data/lib/tdriver-devtools/behaviour/old/xml/update +3 -0
  27. data/lib/tdriver-devtools/behaviour/xml/generate.rb +88 -0
  28. data/lib/tdriver-devtools/behaviour/xml/rdoc_behaviour_xml_generator.rb +1945 -0
  29. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.argument.default.template +1 -0
  30. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.argument.template +3 -0
  31. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.argument_type.template +4 -0
  32. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.exception.template +4 -0
  33. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.method.arguments.template +4 -0
  34. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.method.deprecated.template +3 -0
  35. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.method.exceptions.template +3 -0
  36. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.method.info.template +1 -0
  37. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.method.returns.template +3 -0
  38. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.method.tables.template +3 -0
  39. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.method.template +12 -0
  40. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.returns.template +5 -0
  41. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.table.item.template +1 -0
  42. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.table.row.template +2 -0
  43. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.table.template +8 -0
  44. data/lib/tdriver-devtools/behaviour/xml/templates/behaviour.xml.template +14 -0
  45. data/lib/tdriver-devtools/doc/behaviour_xml/QtExampleGestureBehaviour.xml +138 -0
  46. data/lib/tdriver-devtools/doc/behaviour_xml/created.rid +1 -0
  47. data/lib/tdriver-devtools/doc/behaviour_xml/tdriver.hash +1 -0
  48. data/lib/tdriver-devtools/doc/feature_xml/qt_widget_hold.feature.xml +9 -0
  49. data/lib/tdriver-devtools/doc/feature_xml/qt_widget_tap.feature.xml +9 -0
  50. data/lib/tdriver-devtools/doc/generate.rb +917 -0
  51. data/lib/tdriver-devtools/doc/update +1 -0
  52. data/lib/tdriver-devtools/doc/xslt/html.rb +7 -0
  53. data/lib/tdriver-devtools/doc/xslt/template.xsl +2170 -0
  54. data/lib/tdriver-devtools/doc/xslt/update +3 -0
  55. data/lib/tdriver-devtools/plugin/placeholder.txt +1 -0
  56. data/lib/tdriver-devtools/tdriver-devtools.rb +404 -0
  57. data/lib/tdriver-devtools/tests/feature_tests/example/behaviour_example.rb +100 -0
  58. data/lib/tdriver-devtools/tests/feature_tests/generate.rb +82 -0
  59. data/lib/tdriver-devtools/tests/feature_tests/lib/custom_rdoc_generator.rb +468 -0
  60. data/lib/tdriver-devtools/tests/feature_tests/templates/feature_attribute.template +5 -0
  61. data/lib/tdriver-devtools/tests/feature_tests/templates/feature_method.template +5 -0
  62. data/lib/tdriver-devtools/tests/feature_tests/templates/scenario_attribute.template +5 -0
  63. data/lib/tdriver-devtools/tests/feature_tests/templates/scenario_method.template +5 -0
  64. data/lib/tdriver-devtools/tests/feature_tests/update +3 -0
  65. data/lib/tdriver.rb +23 -0
  66. data/lib/tdriver/base/behaviour/abstract.rb +29 -0
  67. data/lib/tdriver/base/behaviour/behaviours/object_abstract.rb +107 -0
  68. data/lib/tdriver/base/behaviour/behaviours/object_behaviour_composition.rb +99 -0
  69. data/lib/tdriver/base/behaviour/behaviours/object_behaviour_description.rb +278 -0
  70. data/lib/tdriver/base/behaviour/behaviours/object_composition.rb +119 -0
  71. data/lib/tdriver/base/behaviour/factory.rb +495 -0
  72. data/lib/tdriver/base/behaviour/loader.rb +46 -0
  73. data/lib/tdriver/base/command_data/command_data.rb +51 -0
  74. data/lib/tdriver/base/command_data/loader.rb +29 -0
  75. data/lib/tdriver/base/controller/abstraction.rb +56 -0
  76. data/lib/tdriver/base/controller/loader.rb +21 -0
  77. data/lib/tdriver/base/errors.rb +134 -0
  78. data/lib/tdriver/base/loader.rb +47 -0
  79. data/lib/tdriver/base/state_object.rb +373 -0
  80. data/lib/tdriver/base/sut/adapter.rb +54 -0
  81. data/lib/tdriver/base/sut/controller.rb +151 -0
  82. data/lib/tdriver/base/sut/factory.rb +339 -0
  83. data/lib/tdriver/base/sut/generic/behaviours/agent.rb +77 -0
  84. data/lib/tdriver/base/sut/generic/behaviours/application.rb +427 -0
  85. data/lib/tdriver/base/sut/generic/behaviours/controller.rb +67 -0
  86. data/lib/tdriver/base/sut/generic/behaviours/find.rb +107 -0
  87. data/lib/tdriver/base/sut/generic/behaviours/flash_behaviour.rb +337 -0
  88. data/lib/tdriver/base/sut/generic/behaviours/sut.rb +1888 -0
  89. data/lib/tdriver/base/sut/generic/behaviours/switchbox_behaviour.rb +210 -0
  90. data/lib/tdriver/base/sut/generic/behaviours/verification.rb +222 -0
  91. data/lib/tdriver/base/sut/generic/commands/agent.rb +43 -0
  92. data/lib/tdriver/base/sut/generic/commands/application.rb +274 -0
  93. data/lib/tdriver/base/sut/generic/commands/fixture.rb +47 -0
  94. data/lib/tdriver/base/sut/generic/commands/key_sequence.rb +94 -0
  95. data/lib/tdriver/base/sut/generic/commands/screen_capture.rb +64 -0
  96. data/lib/tdriver/base/sut/generic/plugin.rb +97 -0
  97. data/lib/tdriver/base/sut/loader.rb +35 -0
  98. data/lib/tdriver/base/sut/sut.rb +98 -0
  99. data/lib/tdriver/base/test_object/abstract.rb +208 -0
  100. data/lib/tdriver/base/test_object/adapter.rb +740 -0
  101. data/lib/tdriver/base/test_object/behaviours/syncronization.rb +144 -0
  102. data/lib/tdriver/base/test_object/behaviours/test_object.rb +1047 -0
  103. data/lib/tdriver/base/test_object/cache.rb +134 -0
  104. data/lib/tdriver/base/test_object/factory.rb +684 -0
  105. data/lib/tdriver/base/test_object/loader.rb +51 -0
  106. data/lib/tdriver/base/test_object/verification.rb +178 -0
  107. data/lib/tdriver/base/test_object/xml/abstraction.rb +63 -0
  108. data/lib/tdriver/base/test_object/xml/adapter.rb +773 -0
  109. data/lib/tdriver/env.rb +21 -0
  110. data/lib/tdriver/loader.rb +57 -0
  111. data/lib/tdriver/matti.rb +35 -0
  112. data/lib/tdriver/report/error_recovery/tdriver_custom_error_recovery.rb +83 -0
  113. data/lib/tdriver/report/error_recovery/tdriver_error_recovery.rb +168 -0
  114. data/lib/tdriver/report/error_recovery/tdriver_error_recovery_settings.rb +106 -0
  115. data/lib/tdriver/report/report.rb +61 -0
  116. data/lib/tdriver/report/report_api.rb +348 -0
  117. data/lib/tdriver/report/report_combine.rb +86 -0
  118. data/lib/tdriver/report/report_crash_file_capture.rb +178 -0
  119. data/lib/tdriver/report/report_creator.rb +665 -0
  120. data/lib/tdriver/report/report_cucumber.rb +158 -0
  121. data/lib/tdriver/report/report_cucumber_listener.rb +184 -0
  122. data/lib/tdriver/report/report_cucumber_reporter.rb +181 -0
  123. data/lib/tdriver/report/report_data_presentation.rb +156 -0
  124. data/lib/tdriver/report/report_data_table.rb +64 -0
  125. data/lib/tdriver/report/report_execution_statistics.rb +400 -0
  126. data/lib/tdriver/report/report_file_capture.rb +159 -0
  127. data/lib/tdriver/report/report_graph_generator.rb +59 -0
  128. data/lib/tdriver/report/report_grouping.rb +541 -0
  129. data/lib/tdriver/report/report_javascript.rb +199 -0
  130. data/lib/tdriver/report/report_junit_xml.rb +147 -0
  131. data/lib/tdriver/report/report_rspec.rb +108 -0
  132. data/lib/tdriver/report/report_test_case_run.rb +725 -0
  133. data/lib/tdriver/report/report_test_run.rb +1476 -0
  134. data/lib/tdriver/report/report_test_unit.rb +223 -0
  135. data/lib/tdriver/report/report_writer.rb +1621 -0
  136. data/lib/tdriver/tdriver.rb +209 -0
  137. data/lib/tdriver/util/agent/loader.rb +22 -0
  138. data/lib/tdriver/util/agent/service.rb +107 -0
  139. data/lib/tdriver/util/common/array.rb +39 -0
  140. data/lib/tdriver/util/common/boolean.rb +48 -0
  141. data/lib/tdriver/util/common/crc16.rb +149 -0
  142. data/lib/tdriver/util/common/environment.rb +154 -0
  143. data/lib/tdriver/util/common/error.rb +40 -0
  144. data/lib/tdriver/util/common/exception.rb +53 -0
  145. data/lib/tdriver/util/common/exceptions.rb +12 -0
  146. data/lib/tdriver/util/common/file.rb +328 -0
  147. data/lib/tdriver/util/common/gem.rb +109 -0
  148. data/lib/tdriver/util/common/hash.rb +288 -0
  149. data/lib/tdriver/util/common/kernel.rb +253 -0
  150. data/lib/tdriver/util/common/loader.rb +47 -0
  151. data/lib/tdriver/util/common/numeric.rb +159 -0
  152. data/lib/tdriver/util/common/object.rb +159 -0
  153. data/lib/tdriver/util/common/retryable.rb +179 -0
  154. data/lib/tdriver/util/common/stackable.rb +185 -0
  155. data/lib/tdriver/util/common/string.rb +174 -0
  156. data/lib/tdriver/util/database/access.rb +240 -0
  157. data/lib/tdriver/util/database/connection.rb +44 -0
  158. data/lib/tdriver/util/database/error.rb +34 -0
  159. data/lib/tdriver/util/database/loader.rb +28 -0
  160. data/lib/tdriver/util/filters/attribute_filter.rb +121 -0
  161. data/lib/tdriver/util/filters/loader.rb +29 -0
  162. data/lib/tdriver/util/fixture/loader.rb +22 -0
  163. data/lib/tdriver/util/fixture/service.rb +211 -0
  164. data/lib/tdriver/util/hooking/hooking.rb +477 -0
  165. data/lib/tdriver/util/keymap/keymap.rb +81 -0
  166. data/lib/tdriver/util/loader.rb +80 -0
  167. data/lib/tdriver/util/localisation/error.rb +31 -0
  168. data/lib/tdriver/util/localisation/loader.rb +25 -0
  169. data/lib/tdriver/util/localisation/localisation.rb +762 -0
  170. data/lib/tdriver/util/logger/loader.rb +22 -0
  171. data/lib/tdriver/util/logger/logger.rb +591 -0
  172. data/lib/tdriver/util/operator_data/error.rb +29 -0
  173. data/lib/tdriver/util/operator_data/loader.rb +27 -0
  174. data/lib/tdriver/util/operator_data/operator_data.rb +93 -0
  175. data/lib/tdriver/util/other/config.rb +221 -0
  176. data/lib/tdriver/util/parameter/error.rb +48 -0
  177. data/lib/tdriver/util/parameter/loader.rb +25 -0
  178. data/lib/tdriver/util/parameter/parameter.rb +1161 -0
  179. data/lib/tdriver/util/plugin/abstract.rb +61 -0
  180. data/lib/tdriver/util/plugin/error.rb +0 -0
  181. data/lib/tdriver/util/plugin/loader.rb +28 -0
  182. data/lib/tdriver/util/plugin/service.rb +319 -0
  183. data/lib/tdriver/util/recorder/loader.rb +25 -0
  184. data/lib/tdriver/util/recorder/recorder.rb +72 -0
  185. data/lib/tdriver/util/recorder/scripter.rb +294 -0
  186. data/lib/tdriver/util/statistics/statistics.rb +89 -0
  187. data/lib/tdriver/util/user_data/error.rb +28 -0
  188. data/lib/tdriver/util/user_data/loader.rb +25 -0
  189. data/lib/tdriver/util/user_data/user_data.rb +104 -0
  190. data/lib/tdriver/util/video/camera.rb +67 -0
  191. data/lib/tdriver/util/video/camera_linux.rb +153 -0
  192. data/lib/tdriver/util/video/camera_windows.rb +174 -0
  193. data/lib/tdriver/util/video/loader.rb +31 -0
  194. data/lib/tdriver/util/video/video_utils.rb +139 -0
  195. data/lib/tdriver/util/xml/abstraction.rb +117 -0
  196. data/lib/tdriver/util/xml/attribute.rb +32 -0
  197. data/lib/tdriver/util/xml/builder.rb +53 -0
  198. data/lib/tdriver/util/xml/comment.rb +32 -0
  199. data/lib/tdriver/util/xml/document.rb +32 -0
  200. data/lib/tdriver/util/xml/element.rb +32 -0
  201. data/lib/tdriver/util/xml/error.rb +46 -0
  202. data/lib/tdriver/util/xml/loader.rb +62 -0
  203. data/lib/tdriver/util/xml/nil_node.rb +95 -0
  204. data/lib/tdriver/util/xml/nodeset.rb +32 -0
  205. data/lib/tdriver/util/xml/parsers/libxml/libxml.rb +140 -0
  206. data/lib/tdriver/util/xml/parsers/loader.rb +21 -0
  207. data/lib/tdriver/util/xml/parsers/nokogiri/abstraction.rb +167 -0
  208. data/lib/tdriver/util/xml/parsers/nokogiri/attribute.rb +66 -0
  209. data/lib/tdriver/util/xml/parsers/nokogiri/builder.rb +64 -0
  210. data/lib/tdriver/util/xml/parsers/nokogiri/comment.rb +39 -0
  211. data/lib/tdriver/util/xml/parsers/nokogiri/document.rb +66 -0
  212. data/lib/tdriver/util/xml/parsers/nokogiri/element.rb +39 -0
  213. data/lib/tdriver/util/xml/parsers/nokogiri/loader.rb +58 -0
  214. data/lib/tdriver/util/xml/parsers/nokogiri/node.rb +212 -0
  215. data/lib/tdriver/util/xml/parsers/nokogiri/nodeset.rb +237 -0
  216. data/lib/tdriver/util/xml/parsers/nokogiri/text.rb +39 -0
  217. data/lib/tdriver/util/xml/text.rb +32 -0
  218. data/lib/tdriver/util/xml/xml.rb +332 -0
  219. data/lib/tdriver/verify/verify.rb +2398 -0
  220. data/lib/tdriver/version.rb +21 -0
  221. data/xml/behaviours/generic.xml +530 -0
  222. data/xml/defaults/generic.xml +11 -0
  223. data/xml/defaults/sut_generic.xml +8 -0
  224. data/xml/parameters/tdriver_parameters.xml +23 -0
  225. data/xml/templates/generic.xml +292 -0
  226. metadata +324 -0
@@ -0,0 +1,81 @@
1
+ ############################################################################
2
+ ##
3
+ ## Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4
+ ## All rights reserved.
5
+ ## Contact: Nokia Corporation (testabilitydriver@nokia.com)
6
+ ##
7
+ ## This file is part of Testability Driver.
8
+ ##
9
+ ## If you have questions regarding the use of this file, please contact
10
+ ## Nokia at testabilitydriver@nokia.com .
11
+ ##
12
+ ## This library is free software; you can redistribute it and/or
13
+ ## modify it under the terms of the GNU Lesser General Public
14
+ ## License version 2.1 as published by the Free Software Foundation
15
+ ## and appearing in the file LICENSE.LGPL included in the packaging
16
+ ## of this file.
17
+ ##
18
+ ############################################################################
19
+
20
+ module TDriver
21
+
22
+ class KeymapUtilities
23
+
24
+ def self.fetch_keycode( keycode, keymap_hash )
25
+
26
+ # retrieve default keymap name from hash
27
+ keymap = keymap_hash[ :default_keymap ]
28
+
29
+ # convert symbol to string representation for further processing
30
+ keycode_string = keycode.to_s
31
+
32
+ # collect all loaded keymaps, exclude :default_keymap key from hash
33
+ keymaps = keymap_hash.keys.select{ | item | ![ :default_keymap, :all ].include?( item ) }
34
+
35
+ begin
36
+
37
+ # check if environment defined in keycode, e.g. :qt_kDown
38
+ if keycode_string.include?( '_' )
39
+
40
+ if /(#{ keymaps.collect{ | env | "#{ env.to_s }_" }.join('|') })(.+)/i.match( keycode_string )
41
+
42
+ # set new keymap value and convert to symbol, e.g. :qt from :qt_kDown
43
+ keymap = $1.chop.to_sym
44
+
45
+ # set correct keycode value and convert to symbol, e.g. :kDown from :qt_kDown
46
+ keycode = $2.to_sym
47
+
48
+ end
49
+
50
+ # retrieve symbol from keymap
51
+ keymap_hash[ keymap ][ keycode ]
52
+
53
+ else
54
+
55
+ begin
56
+
57
+ # try to retrieve from default keymap; raises exception if key not found
58
+ keymap_hash[ keymap ][ keycode ]
59
+
60
+ rescue
61
+
62
+ # if we didn't find the key, let's try finding from mixed keymap; mixed keymap has all loaded keycodes
63
+ # keycodes are merged to existing hash when loading new keymap on top
64
+ # raises exception if key not found
65
+ keymap_hash[ :all ][ keycode ]
66
+
67
+ end
68
+
69
+ end
70
+
71
+ rescue
72
+
73
+ raise ArgumentError, "Scan code for #{ keycode.inspect } not defined in #{ keymap } keymap"
74
+
75
+ end
76
+
77
+ end
78
+
79
+ end # KeymapUtilities
80
+
81
+ end # TDriver
@@ -0,0 +1,80 @@
1
+ ############################################################################
2
+ ##
3
+ ## Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4
+ ## All rights reserved.
5
+ ## Contact: Nokia Corporation (testabilitydriver@nokia.com)
6
+ ##
7
+ ## This file is part of Testability Driver.
8
+ ##
9
+ ## If you have questions regarding the use of this file, please contact
10
+ ## Nokia at testabilitydriver@nokia.com .
11
+ ##
12
+ ## This library is free software; you can redistribute it and/or
13
+ ## modify it under the terms of the GNU Lesser General Public
14
+ ## License version 2.1 as published by the Free Software Foundation
15
+ ## and appearing in the file LICENSE.LGPL included in the packaging
16
+ ## of this file.
17
+ ##
18
+ ############################################################################
19
+
20
+ require 'singleton'
21
+
22
+ require 'rubygems'
23
+
24
+ [
25
+ # hooking module - should be loaded first due to above modules uses its functions
26
+ 'hooking/hooking.rb',
27
+
28
+ # common utility modules
29
+ 'common/loader.rb',
30
+
31
+ # logger module
32
+ 'logger/logger.rb',
33
+
34
+ # parameter modules
35
+ 'xml/loader.rb',
36
+
37
+ # statistics module
38
+ 'statistics/statistics.rb',
39
+
40
+ # filter modules
41
+ 'filters/loader.rb',
42
+
43
+ # plugin service modules
44
+ 'plugin/loader.rb',
45
+
46
+ # parameter modules
47
+ 'parameter/loader.rb',
48
+
49
+ # database access module
50
+ 'database/loader.rb',
51
+
52
+ # localisation module
53
+ 'localisation/loader.rb',
54
+
55
+ # user data module
56
+ 'user_data/loader.rb',
57
+
58
+ # operator data module
59
+ 'operator_data/loader.rb',
60
+
61
+ # recorder and scripter modules
62
+ 'recorder/loader.rb',
63
+
64
+ # agent service command modules
65
+ 'agent/loader.rb',
66
+
67
+ # fixture service modules
68
+ 'fixture/loader.rb',
69
+
70
+ # video capture/util modules
71
+ 'video/loader.rb',
72
+
73
+ # keymap utility modules
74
+ 'keymap/keymap.rb'
75
+
76
+ ].each{ | filename |
77
+
78
+ require File.expand_path( File.join( File.dirname( __FILE__ ), filename ) )
79
+
80
+ }
@@ -0,0 +1,31 @@
1
+ ############################################################################
2
+ ##
3
+ ## Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4
+ ## All rights reserved.
5
+ ## Contact: Nokia Corporation (testabilitydriver@nokia.com)
6
+ ##
7
+ ## This file is part of Testability Driver.
8
+ ##
9
+ ## If you have questions regarding the use of this file, please contact
10
+ ## Nokia at testabilitydriver@nokia.com .
11
+ ##
12
+ ## This library is free software; you can redistribute it and/or
13
+ ## modify it under the terms of the GNU Lesser General Public
14
+ ## License version 2.1 as published by the Free Software Foundation
15
+ ## and appearing in the file LICENSE.LGPL included in the packaging
16
+ ## of this file.
17
+ ##
18
+ ############################################################################
19
+
20
+ module MobyUtil
21
+
22
+ # This error should be raised when referred language is not found
23
+ class LanguageNotFoundError < CustomError; end;
24
+
25
+ # This error should be raised when referred table is not found
26
+ class TableNotFoundError < CustomError; end;
27
+
28
+ # This error should be raised when referred logical name is not found for specified language
29
+ class LogicalNameNotFoundError < CustomError; end;
30
+
31
+ end
@@ -0,0 +1,25 @@
1
+ ############################################################################
2
+ ##
3
+ ## Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4
+ ## All rights reserved.
5
+ ## Contact: Nokia Corporation (testabilitydriver@nokia.com)
6
+ ##
7
+ ## This file is part of Testability Driver.
8
+ ##
9
+ ## If you have questions regarding the use of this file, please contact
10
+ ## Nokia at testabilitydriver@nokia.com .
11
+ ##
12
+ ## This library is free software; you can redistribute it and/or
13
+ ## modify it under the terms of the GNU Lesser General Public
14
+ ## License version 2.1 as published by the Free Software Foundation
15
+ ## and appearing in the file LICENSE.LGPL included in the packaging
16
+ ## of this file.
17
+ ##
18
+ ############################################################################
19
+
20
+ # localisation related errors
21
+ require File.expand_path( File.join( File.dirname( __FILE__ ), 'error.rb' ) )
22
+
23
+ # localisation module implementation - load only if needed
24
+ require File.expand_path( File.join( File.dirname( __FILE__ ), 'localisation.rb' ) )
25
+
@@ -0,0 +1,762 @@
1
+ ############################################################################
2
+ ##
3
+ ## Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4
+ ## All rights reserved.
5
+ ## Contact: Nokia Corporation (testabilitydriver@nokia.com)
6
+ ##
7
+ ## This file is part of Testability Driver.
8
+ ##
9
+ ## If you have questions regarding the use of this file, please contact
10
+ ## Nokia at testabilitydriver@nokia.com .
11
+ ##
12
+ ## This library is free software; you can redistribute it and/or
13
+ ## modify it under the terms of the GNU Lesser General Public
14
+ ## License version 2.1 as published by the Free Software Foundation
15
+ ## and appearing in the file LICENSE.LGPL included in the packaging
16
+ ## of this file.
17
+ ##
18
+ ############################################################################
19
+
20
+ # TODO: refactor to use MobyUtil::XML
21
+ require 'nokogiri'
22
+
23
+ # Utility for handling localisation database
24
+ module MobyUtil
25
+
26
+ class Localisation
27
+
28
+ # == Language maping cross-referenced from Nokia Shared Lancuage Codes and Symbian
29
+ #
30
+ # Please follow Nokia Language Guidelines.
31
+ #
32
+ # Its also enumerated by TLanguage in e32lang.h in the Symbian code.
33
+ # The ones only on e32lang.h are commented out
34
+ @language_code_map = {
35
+ "English" => ["en", "01"],
36
+ "French" => ["fr", "02"],
37
+ "German" => ["de", "03"],
38
+ "Spanish" => ["es", "04"],
39
+ "Italian" => ["it", "05"],
40
+ "Swedish" => ["sv", "06"],
41
+ "Danish" => ["da", "07"],
42
+ "Norwegian" => ["no", "08"],
43
+ "Finnish" => ["fi", "09"],
44
+ "English US" => ["en_US", "10"],
45
+ "en_US" => ["en_US", "14346"],
46
+ # "Swiss French" => ["SF", "11"],
47
+ # "Swiss German" => ["SG", "12"],
48
+ "Portuguese" => ["pt", "13"],
49
+ "Turkish" => ["tr", "14"],
50
+ "Icelandic" => ["is", "15"],
51
+ "Russian" => ["ru", "16"],
52
+ "Hungarian" => ["hu", "17"],
53
+ "Dutch" => ["nl", "18"],
54
+ # "Belgian Flemish" => ["BL", "19"],
55
+ # "Australian" => ["AU", "20"],
56
+ # "Belgian French" => ["BF", "21"],
57
+ # "Austrian" => ["AS", "22"],
58
+ # "New Zealand" => ["NZ", "23"],
59
+ # "International French" => ["IR", "24"],
60
+ "Czech" => ["cs", "25"],
61
+ "Slovak" => ["sk", "26"],
62
+ "Polish" => ["pl", "27"],
63
+ "Slovenian" => ["sl", "28"],
64
+ "Chinese TW" => ["zh_TW", "29"],
65
+ "Chinese HK" => ["zh_HK", "30"],
66
+ "Chinese" => ["zh", "31"],
67
+ "Japanese" => ["ja", "32"],
68
+ "Thai" => ["th", "33"],
69
+ "Afrikaans" => ["af", "34"],
70
+ "Albanian" => ["sq", "35"],
71
+ "Amharic" => ["am", "36"],
72
+ "Arabic" => ["ar", "37"],
73
+ "Armenian" => ["hy", "38"],
74
+ "Filipino" => ["tl", "39"],
75
+ "Belarusian" => ["be", "40"],
76
+ "Bengali" => ["bn", "41"],
77
+ "Bulgarian" => ["bg", "42"],
78
+ # "Burmese" => ["MY", "43"],
79
+ "Catalan" => ["ca", "44"],
80
+ "Croatian" => ["hr", "45"],
81
+ # "Canadian English" => ["CE", "46"],
82
+ # "International English" => ["IE", "47"],
83
+ # "South African English" => ["SA", "48"],
84
+ "Estonian" => ["et", "49"],
85
+ "Persian" => ["fa", "50"],
86
+ "French CA" => ["fr_CA", "51"],
87
+ "fr_CA" => ["fr_CA", "14387"],
88
+ # "Scots Gaelic" => ["GD", "52"],
89
+ "Georgian" => ["ka", "53"],
90
+ "Greek" => ["el", "54"],
91
+ # "Cyprus Greek" => ["CG", "55"],
92
+ "Gujarati" => ["gu", "56"],
93
+ "Hebrew" => ["he", "57"],
94
+ "Hindi" => ["hi", "58"],
95
+ "Indonesian" => ["id", "59"],
96
+ # "Irish" => ["GA", "60"],
97
+ # "Swiss Italian" => ["SZ", "61"],
98
+ "Kannada" => ["kn", "62"],
99
+ "Kazakh" => ["kk", "63"],
100
+ "Khmer" => ["km", "64"],
101
+ "Korean" => ["ko", "65"],
102
+ # "Lao" => ["lo", "66"],
103
+ "Latvian" => ["lv", "67"],
104
+ "Lithuanian" => ["lt", "68"],
105
+ "Macedonian" => ["mk", "69"],
106
+ "Malay" => ["ms", "70"],
107
+ "Malayalam" => ["ml", "71"],
108
+ "Marathi" => ["mr", "72"],
109
+ # "Moldavian" => ["MO", "73"],
110
+ "Mongolian" => ["mn", "74"],
111
+ # "Norwegian Nynorsk" => ["nn", "75"],
112
+ "Portuguese BR" => ["pt_BR", "76"],
113
+ "pt_AM" => ["pt_AM", "14412"],
114
+ "Punjabi" => ["pa", "77"],
115
+ "Romanian" => ["ro", "78"],
116
+ "Servian" => ["sr", "79"],
117
+ "Sinhala" => ["si", "80"],
118
+ # "Somali" => ["SO", "81"],
119
+ # "International Spanish" => ["OS", "82"],
120
+ "Spanish AM" => ["es_419", "83"],
121
+ "sp_AM" => ["sp_AM", "14419"],
122
+ "sp_PA" => ["sp_PA", "6154"],
123
+ "sp_UR" => ["sp_UR", "14346"],
124
+ "Swahili" => ["sw", "84"],
125
+ # "Finland Swedish" => ["FS", "85"],
126
+ "Tamil" => ["ta", "87"],
127
+ "Telugu" => ["te", "88"],
128
+ # "Tibetan" => ["BO", "89"],
129
+ # "Tigrinya" => ["TI", "90"],
130
+ # "Cyprus Turkish" => ["CT", "91"],
131
+ "Turkem" => ["tk", "92"],
132
+ "Ukranian" => ["uk", "93"],
133
+ "Urdu" => ["ur", "94"],
134
+ "Vietnamese" => ["vi", "96"],
135
+ # "Welsh" => ["CY", "97"],
136
+ "Zulu" => ["zu", "98"],
137
+ # "Manufacturer English" => ["ME", "100"],
138
+ "Sesotho" => ["st", "101"],
139
+ "Basque" => ["eu", "102"],
140
+ "Galician" => ["gl", "103"],
141
+ # "Javanese" => ["", "104"],
142
+ # "Maithili" => ["", "105"],
143
+ # "Azerbaijani Latin" => ["", "106"],
144
+ "Azerbaijani Cyrillic" => ["az", "107"],
145
+ "Oriya" => ["or", "108"],
146
+ # "Bhojpuri" => ["", "109"],
147
+ # "Sundanese" => ["", "110"],
148
+ # "Kurdish Latin" => ["", "111"],
149
+ # "Kurdish Arabic" => ["", "112"],
150
+ "Pashto" => ["ps", "113"],
151
+ "Hausa" => ["ha", "114"],
152
+ #"Oromo" => ["", "115"],
153
+ # "Uzbek Latin" => [", "116"],
154
+ "Uzbek Cyrillic" => ["uz", "117"],
155
+ # "Sindhi Arabic" => ["", "118"],
156
+ # "Sindhi Devanagari" => ["", "119"],
157
+ "Yoruba" => ["yo", "120"],
158
+ # "Cebuano" => ["", "121"],
159
+ "Igbo" => ["ig", "122"],
160
+ "Malagasy" => ["mg", "123"],
161
+ # "Nepali" => ["", "124"],
162
+ "Assamese" => ["as", "125"],
163
+ # "Shona" => ["", "126"],
164
+ # "Zhuang" => ["", "127"],
165
+ # "Madurese" => ["", "127"],
166
+ "English Apac" => ["EA", "129"], # In e32long.h, Pearl script, but not in Nokia Language Codes Standard
167
+ "English Taiwan" => ["YW", "157"], # In e32long.h, Pearl script, but not in Nokia Language Codes Standard
168
+ "English Hong Kong" => ["YH", "158"], # In e32long.h, Pearl script, but not in Nokia Language Codes Standard
169
+ "English PRC" => ["YP", "159"], # In e32long.h, Pearl script, but not in Nokia Language Codes Standard
170
+ "English Japan" => ["YJ", "160"], # In e32long.h, Pearl script, but not in Nokia Language Codes Standard
171
+ "English Thailand" => ["YT", "161"], # In e32long.h, Pearl script, but not in Nokia Language Codes Standard
172
+ # "Fulfulde" => ["", "162"],
173
+ # "Tamazight" => ["", "163"],
174
+ # "BolivianQuechua" => ["", "164"],
175
+ # "PeruQuechua" => ["", "165"],
176
+ # "EcuadorQuechua" => ["", "166"],
177
+ "Tajik_Cyrillic" => ["tg", "167"],
178
+ # "Tajik_PersoArabic" => ["", "168"],
179
+ # "Nyanja" => ["", "169"],
180
+ # "HaitianCreole" => ["", "170"],
181
+ # "Lombard" => ["", "171"],
182
+ # "Koongo" => ["", "172"],
183
+ # "Akan" => ["", "173"],
184
+ # "Hmong" => ["", "174"],
185
+ # "Yi" => ["", "175"],
186
+ # "Tshiluba" => ["", "176"],
187
+ # "Ilocano" => ["", "177"],
188
+ # "Uyghur" => ["", "178"],
189
+ # "Neapolitan" => ["", "179"],
190
+ # "Rwanda" => ["", "180"],
191
+ "Xhosa" => ["xh", "181"],
192
+ # "Balochi" => ["", "182"],
193
+ # "Hiligaynon" => {"", "183"],
194
+ # "Minangkabau" => ["", "184"],
195
+ # "Makhuwa" => ["", "185"],
196
+ # "Santali" => ["", "186"],
197
+ # "Gikuyu" => ["", "187"],
198
+ # "Moore" => ["", "188"],
199
+ # "Guarani" => ["", "189"],
200
+ # "Rundi" => ["", "190"],
201
+ # "Romani_Latin" => ["", "191"],
202
+ # "Romani_Cyrillic" => ["", "192"],
203
+ # "Tswana" => ["", "193"],
204
+ # "Kanuri" => ["", "194"],
205
+ # "Kashmiri Devanagari" => ["", "195"],
206
+ "Kashmiri Perso Arabic" => ["ks", "196"],
207
+ # "Umbundu" => ["", "197"],
208
+ # "Konkani" => ["", "198"],
209
+ # "Balinese" => ["", "199"],
210
+ # "Northern Sotho" => ["", "200"],
211
+ # "Wolof" => ["", "201"],
212
+ # "Bemba" => ["", "202"],
213
+ # "Tsonga" => ["", "203"],
214
+ # "Yiddish" => ["", "204"],
215
+ "Kirghiz" => ["ky", "205"],
216
+ # "Ganda" => ["", "206"],
217
+ # "Soga" => ["", "207"],
218
+ # "Mbundu" => ["", "208"],
219
+ # "Bambara" => ["", "209"],
220
+ # "Central Aymara" => ["", "210"],
221
+ # "Zarma" => ["", "211"],
222
+ "Lingala" => ["ln", "212"],
223
+ # "Bashkir" => ["", "213"],
224
+ # "Chuvash" => ["", "214"],
225
+ # "Swati" => ["", "215"],
226
+ # "Tatar" => ["", "216"],
227
+ # "Southern Ndebele" => ["", "217"],
228
+ # "Sardinian" => ["", "218"],
229
+ # "Scots" => ["", "219"],
230
+ # "Meitei" => ["", "220"],
231
+ # "Walloon" => ["", "221"],
232
+ # "Kabardian" => ["", "222"],
233
+ # "Mazanderani" => ["", "223"],
234
+ # "Gilaki" => ["", "224"],
235
+ # "Shan" => ["", "225"],
236
+ # "Luyia" => ["", "226"],
237
+ # "Luo" => ["", "227"],
238
+ # "Sukuma" => ["", "228"],
239
+ # "Aceh" => ["", "229"],
240
+ "English_India" => ["en_in", "230"], # In e32long.h, Pearl script, but not in Nokia Language Codes Standard
241
+ "Malay Apac" => ["MA", "326"], # In e32long.h, Pearl script, but not in Nokia Language Codes Standard
242
+ "Indonesian Apac" =>["id_ap", "327"],
243
+ "English Bangladesh" =>["en_ba", "328"],
244
+ # "Bengali IN" => ["bn_IN", ""],
245
+ # "Bosnian" => ["bs", ""],
246
+ }
247
+
248
+
249
+
250
+
251
+ # == description
252
+ # Function to fetch a translation for a given logical name from the localisation DB
253
+ #
254
+ # == arguments
255
+ # logical_name
256
+ # String
257
+ # description: Logical name (LNAME) of the item to be translated. If prefix for User Information or Operator Data are used then the appropiate retrieve methods will be called
258
+ # example: "txt_button_ok"
259
+ # Symbol
260
+ # description: Symbol form of the logical name (LNAME) of the item to be translated.
261
+ # example: :txt_button_ok
262
+ #
263
+ # language
264
+ # String
265
+ # description: Name of the language column to be used. This is normally the language postfix found on the .ts, .qm translation files. On .loc file postfix numbers are mapped to similar language codes according to standards in Symbian literature and others, check the localization.db implementation file for the full mapping.
266
+ # example: "en" or "es_416" or "en_us"
267
+ #
268
+ # table_name
269
+ # String
270
+ # description: Name of the translation table to use from the localisation DB
271
+ # example: "B10_1_week201042_loc"
272
+ #
273
+ # file_name
274
+ # String
275
+ # description: Optional FNAME search argument for the translation. The FNAME column stores the application name that the translation belongs to
276
+ # example: "calendar"
277
+ #
278
+ # plurality
279
+ # String
280
+ # description: Optional PLURALITY search argument for the translation
281
+ # example: "a" or "singular"
282
+ #
283
+ # lengthvariant
284
+ # String
285
+ # description: Optional LENGTHVAR search argument for the translation (1-9)
286
+ # example: "1"
287
+ #
288
+ # == returns
289
+ # String
290
+ # description: Translation matching the logical_name
291
+ # example: "Ok"
292
+ # Array
293
+ # description: If multiple translations have been found for the search conditions an Array with all Strings be returned
294
+ # example: ["Ok", "OK"]
295
+ #
296
+ # == exceptions
297
+ # LanguageNotFoundError
298
+ # description: In case language is not found
299
+ #
300
+ # LogicalNameNotFoundError
301
+ # description: In case no logical name is not found for current language
302
+ #
303
+ # TableNotFoundError
304
+ # description: If the table name argument is not valid
305
+ #
306
+ # SqlError
307
+ # description: In case there are problems with the database connectivity
308
+ #
309
+ def self.translation( logical_name, language, table_name, file_name = nil , plurality = nil, lengthvariant = nil )
310
+
311
+ raise LogicalNameNotFoundError.new( "Logical name cannot be nil" ) if logical_name == nil
312
+ raise LanguageNotFoundError.new( "Language cannot be nil" ) if language == nil
313
+ raise TableNotFoundError.new( "Table name cannot be nil" ) if table_name == nil
314
+
315
+ # Avoid system column names for language columns and user only downcase
316
+ language = language.to_s.downcase
317
+ if language.eql? "id" or language.eql? "fname" or language.eql? "lname" or language.eql? "plurality" or language.eql? "lengthvar"
318
+ language += "_"
319
+ end
320
+
321
+ db_type = $parameters[ :localisation_db_type, nil ]
322
+ host = $parameters[ :localisation_server_ip ]
323
+ username = $parameters[ :localisation_server_username ]
324
+ password = $parameters[ :localisation_server_password ]
325
+ database_name = $parameters[ :localisation_server_database_name ]
326
+
327
+ db_connection = DBConnection.new( db_type, host, database_name, username, password )
328
+
329
+ query_string = "select `#{ language }` from #{ table_name } where lname = '#{ logical_name }'"
330
+ query_string += " and `FNAME` = '#{ file_name }'" unless file_name.nil?
331
+ query_string += " and `PLURALITY` = '#{ plurality }'" unless plurality.nil?
332
+ query_string += " and `LENGTHVAR` = '#{ lengthvariant }'" unless lengthvariant.nil?
333
+ query_string += " and `#{ language }` <> \'#MISSING\'"
334
+
335
+ begin
336
+ # Returns a uniform set of results as an array of rows, rows beeing an array of values ( Array<Array<String>> )
337
+ result = MobyUtil::DBAccess.query( db_connection, query_string )
338
+ rescue
339
+ # if column referring to language is not found then raise error for language not found
340
+ raise LanguageNotFoundError.new( "No language '#{ language }' found" ) unless $!.message.index( "Unknown column" ) == nil
341
+ raise SqlError.new( $!.message )
342
+ end
343
+
344
+ # Return only the first column of the row or and array of the values of the first column if multiple rows have been found
345
+ raise LogicalNameNotFoundError.new( "No translation found for logical name '#{ logical_name }' in language '#{ language }' with given plurality and lengthvariant." ) if ( result.empty?)
346
+ if result.length > 1
347
+ # Result is an Array of rows (Array<String>)! We want the first column of each row.
348
+ result_array = Array.new
349
+ result.each do |row|
350
+ result_array << row[0]
351
+ end
352
+ return result_array
353
+ else
354
+ # Result is an Array of rows (Array<String>)! We want the first column of the first row.
355
+ return result[0][0]
356
+ end
357
+
358
+ end
359
+
360
+ # == description
361
+ # Function upload translations in a given Qt Linguist translation file to the localisation DB
362
+ #
363
+ # == arguments
364
+ # file
365
+ # String
366
+ # description: Path to Qt Linguist translation file to upload. Both .ts and .qm files are allowed.
367
+ # example: "accessories_ar.ts"
368
+ #
369
+ # table_name
370
+ # String
371
+ # description: Name of the translation table to use form the localisation DB
372
+ # example: "B10_1_week201042_loc"
373
+ #
374
+ # db_connection
375
+ # MobyUtil::DBConnection
376
+ # description: A DBConnection object contains all the connection details required to connect to a SQL DB (mysql or sqlite)
377
+ # example: "MobyUtil::DBConnection.new('mysql', '192.168.0.1', 'tdriver_locale', 'username', 'password')"
378
+ #
379
+ # column_names_map
380
+ # Hash
381
+ # description: Use this parameter to change the default language names. The default language postfix translation files (.ts, .qm or .loc) as keys and the desired column names as values
382
+ # example: {"en" => "en_GB"}
383
+ #
384
+ # record_sql
385
+ # Bool
386
+ # description: When this flag is set to true then
387
+ # example: true
388
+ #
389
+ # == returns
390
+ #
391
+ # == throws
392
+ # ArgumentError
393
+ # description: When arguments provided are not valid
394
+ #
395
+ # Exception
396
+ # description: When its not possible to parse the file provided
397
+ #
398
+ def self.upload_translation_file( file, table_name, db_connection = nil, column_names_map = {}, record_sql = false)
399
+ raise ArgumentError.new("") if file.nil? or file.empty?
400
+ raise ArgumentError.new("") if table_name.nil? or table_name.empty?
401
+
402
+ # Get a connection to the DB
403
+ if db_connection.nil? or !db_connection.kind_of? MobyUtil::DBConnection
404
+ db_type = $parameters[ :localisation_db_type ]
405
+ host = $parameters[ :localisation_server_ip ]
406
+ database_name = $parameters[ :localisation_server_database_name ]
407
+ username = $parameters[ :localisation_server_username ]
408
+ password = $parameters[ :localisation_server_password ]
409
+
410
+ db_connection = DBConnection.new( db_type, host, database_name, username, password )
411
+ end
412
+ if file.match(/.*\.ts/) or file.match(/.*\.qm/)
413
+ # Check File and convert to TS File if needed
414
+ tsFile = MobyUtil::Localisation.convert_to_ts( file )
415
+ raise Exception.new("Failed to convert #{file} to .ts") if tsFile == nil
416
+ # Collect data for INSERT query from TS File
417
+ language, data = MobyUtil::Localisation.parse_ts_file( tsFile, column_names_map )
418
+ raise Exception.new("Error while parsing #{file}.") if language == nil or data == ""
419
+ elsif file.match(/.*\.loc/)
420
+ language, data = MobyUtil::Localisation.parse_loc_file( file, column_names_map )
421
+ raise Exception.new("Error while parsing #{file}. The file might have no translations.") if language.nil? or language.empty? or data.nil? or data.empty?
422
+ end
423
+ # Upload language data to DB for current language file
424
+ MobyUtil::Localisation.upload_data( language, data, table_name, db_connection, record_sql )
425
+ end
426
+
427
+
428
+
429
+ private
430
+
431
+
432
+ # == description
433
+ # Checks Qt Linguist translation file for validity and converts to TS if needed
434
+ #
435
+ # == arguments
436
+ # file
437
+ # String
438
+ # description: Name (and path) of the Qt Linguist translation file (.ts or .qm)
439
+ # example: "calendar.qm"
440
+ #
441
+ # == returns
442
+ # String
443
+ # description: Name (and path) of the checked and maybe converted .ts Qt Linguist translation file
444
+ #
445
+ # == throws
446
+ #
447
+ def self.convert_to_ts(file)
448
+ if !File.exists?(file)
449
+ puts "[WARNING] File '" + file + "' not found. Skiping."
450
+ file = nil
451
+ elsif (nil == file.match(/.*\.ts/) and nil == file.match(/.*\.qm/) )
452
+ puts "[WARNING] Unknown file extension. Skiping. \n\n" + file
453
+ file = nil
454
+ elsif ( match = file.match(/(.*)\.qm/) )
455
+ if(! system "lconvert -o " + match[1] + ".ts " + file )
456
+ puts "[ERROR] lconvert can't convert .qm file to .ts. Skiping. \n\n" + match[0]
457
+ return nil
458
+ end
459
+ file = match[1] + ".ts"
460
+ end
461
+ file
462
+ end
463
+
464
+
465
+ # == description
466
+ # Extracts translation data from TS file
467
+ #
468
+ # == arguments
469
+ # file
470
+ # String
471
+ # description: Name (and path) of the Qt Linguist translation file (.ts or .qm)
472
+ # example: "calendar.qm"
473
+ #
474
+ # column_names_map
475
+ # Hash
476
+ # description: Hash with the language codes from the translation files as keys and the desired column names as values
477
+ # example: {"en" => "en_GB"}
478
+ #
479
+ # == returns
480
+ # String
481
+ # description: Name (and path) of the checked and maybe converted .ts Qt Linguist translation file
482
+ #
483
+ # Array
484
+ # description: Two dimentional Array with columns [ FNAME, Source, Translation, Plurality, Lengthvariant Priority ]
485
+ #
486
+ # == throws
487
+ #
488
+
489
+ def self.parse_ts_file(file, column_names_map = {} )
490
+ # Read TS file
491
+ open_file = File.new( file )
492
+ doc = Nokogiri.XML( open_file )
493
+ # language = doc.xpath('.//TS').attribute("language")
494
+ # IF filename-to-columnname mapping is provided update language
495
+ fname, language = parseFName(file)
496
+ if (!column_names_map.empty?)
497
+ language_code = file.split('/').last.gsub(fname + "_" ){|s| ""}.gsub(".ts"){|s| ""}
498
+ language = column_names_map[ language_code ] if column_names_map.key?( language_code )
499
+ end
500
+ if (language == nil)
501
+ puts "[WARNING] The input file is missing the language attribute on it's <TS> element. Skiping. \n\n"
502
+ return nil, nil
503
+ end
504
+ # Collect data for INSERT query
505
+ data = []
506
+ doc.xpath('.//message').each do |node|
507
+ begin
508
+ nodeId = ""
509
+ nodeTranslation = ""
510
+ nodePlurality = "NULL"
511
+ nodeLengthVar = ""
512
+ # set nodeId
513
+ #raise Exception if node.xpath('@id').inner_text() == ""
514
+ if node.xpath('@id').inner_text() != ""
515
+ nodeId = node.xpath('@id').inner_text()
516
+ else
517
+ nodeId = node.xpath('.//source').inner_text()
518
+ end
519
+ # Parse Numerus(LengthVar), or Numerus or LengthVar or translation direclty
520
+ if ! node.xpath('.//translation/numerusform').empty?
521
+ # puts ">>> Numerusform"
522
+ priority = 1
523
+ plurality = 'NULL'
524
+ node.xpath('.//translation/numerusform').each do |numerus|
525
+ nodePlurality = numerus.xpath('@plurality').inner_text()
526
+ nodePlurality = plurality.to_s if nodePlurality.empty?
527
+ if ! numerus.xpath('.//lengthvariant').empty?
528
+ # puts " >>> Lengthvar"
529
+ priority = 1
530
+ numerus.xpath('.//lengthvariant').each do |lenghtvar|
531
+ nodeLengthVar = lenghtvar.xpath('@priority').inner_text()
532
+ nodeLengthVar = priority.to_s if nodeLengthVar.empty?
533
+ nodeTranslation = lenghtvar.inner_text()
534
+ data << [ fname, nodeId, nodeTranslation, nodePlurality, nodeLengthVar ]
535
+ priority += 1
536
+ end
537
+ else
538
+ nodeTranslation = numerus.inner_text()
539
+ data << [ fname, nodeId, nodeTranslation, nodePlurality, nodeLengthVar = '1' ]
540
+ priority += 1
541
+ end
542
+ end
543
+ elsif ! node.xpath('.//translation/lengthvariant').empty?
544
+ # puts ">>> Lengthvar"
545
+ priority = 1
546
+ node.xpath('.//translation/lengthvariant').each do |lenghtvar|
547
+ nodeLengthVar = lenghtvar.xpath('@priority').inner_text()
548
+ nodeLengthVar = priority.to_s if nodeLengthVar.empty?
549
+ nodeTranslation = lenghtvar.inner_text()
550
+ data << [ fname, nodeId, nodeTranslation, nodePlurality, nodeLengthVar ]
551
+ priority += 1
552
+ end
553
+ else
554
+ # When no lengthvar is provided we now assign priority '1' by default
555
+ # puts ">>> Translation"
556
+ nodeTranslation = node.xpath('.//translation').inner_text()
557
+ data << [ fname, nodeId, nodeTranslation, nodePlurality, nodeLengthVar = '1' ]
558
+ end
559
+ rescue Exception # ignores bad elements or elements with empty translations for now
560
+ end
561
+ end
562
+ open_file.close
563
+ return language, data
564
+ end
565
+
566
+ #
567
+ # Note: for .loc files the colum mapping is done with the Language code number on the filenames
568
+ #
569
+ def self.parse_loc_file(file, column_names_map = {})
570
+ begin
571
+
572
+ data = []
573
+ file.split('/').last.match(/(.*)_(\w{2,5}).loc/)
574
+ fname = $1
575
+ language_number = $2
576
+ # select returns an array of [language, codes] that suite the conditional
577
+ # codes is the array ["NokiaCode(2-leter)", "SymbianCode(number)"]
578
+ language = @language_code_map.select{|lang,codes| codes[1] == language_number}.to_a[0][1][0] # Array conversion for ruby 1.9 compatibility
579
+ language = column_names_map[ language_number ] if !column_names_map.empty? and column_names_map.key?( language_number )
580
+
581
+ io = open(file)
582
+ while line = io.gets
583
+ if line.match(/#define ([a-zA-Z1-9\d\_]*) \"(.*)\"/)
584
+ lname = $1
585
+ translation = $2
586
+ # When no lengthvar is provided we now assign priority '1' by default
587
+ data << [ fname, lname, translation, plurality = "", lengthvariant = "1" ]
588
+ end
589
+ end
590
+ io.close
591
+ #puts language
592
+ #p data
593
+ return language, data
594
+ rescue Exception => e
595
+ #puts e.message
596
+ #puts e.backtrace
597
+ end
598
+ end
599
+
600
+ # == description
601
+ # Uploads language data to Localisation DB and optionally records the sql queries on a file
602
+ #
603
+ def self.upload_data( language, data, table_name, db_connection, record_sql = false )
604
+
605
+ raise Exception.new("Language not provided.") if language.nil? or language.to_s.empty?
606
+ raise Exception.new("No data povided. Please make sure the source of your data is valid.") if data.nil? or data.empty?
607
+ raise Exception.new("No table name provided.") if table_name.nil? or table_name.empty?
608
+ raise Exception.new("Invalid connection object provided.") if db_connection.nil? or !db_connection.kind_of? MobyUtil::DBConnection
609
+
610
+ # Avoid system column names for language columns and user only downcase
611
+ language = language.to_s.downcase
612
+ if language.eql? "id" or language.eql? "fname" or language.eql? "lname" or language.eql? "plurality" or language.eql? "lengthvar"
613
+ language += "_"
614
+ end
615
+
616
+ sql_file = File.open(table_name + ".#{db_connection.db_type}.sql", 'a')
617
+
618
+ # CREATE TABLE if doesn't exist (language columns to be created as needed)
619
+ # When no lengthvar is provided we now assign priority '1' by default
620
+ case db_connection.db_type
621
+ when "mysql"
622
+ query_string = "CREATE TABLE IF NOT EXISTS " + table_name + " (
623
+ `ID` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
624
+ `FNAME` VARCHAR(150) NOT NULL COLLATE latin1_general_ci,
625
+ `LNAME` VARCHAR(150) NOT NULL COLLATE latin1_general_ci,
626
+ `PLURALITY` VARCHAR(50) NULL DEFAULT NULL COLLATE latin1_general_ci,
627
+ `LENGTHVAR` INT(10) NULL DEFAULT '1',
628
+ PRIMARY KEY (`ID`),
629
+ UNIQUE INDEX `FileLogicNameIndex` (`FNAME`,`LNAME`, `PLURALITY`, `LENGTHVAR`),
630
+ INDEX `LNameIndex` (`LNAME`)
631
+ ) COLLATE=utf8_general_ci;"
632
+ MobyUtil::DBAccess.query( db_connection, query_string )
633
+ sql_file.write( query_string + "\n" ) if record_sql
634
+ when "sqlite"
635
+ query_string = "CREATE TABLE IF NOT EXISTS " + table_name + " (
636
+ `ID` INTEGER PRIMARY KEY AUTOINCREMENT,
637
+ `FNAME` VARCHAR(150) NOT NULL,
638
+ `LNAME` VARCHAR(150) NOT NULL,
639
+ `PLURALITY` VARCHAR(50) DEFAULT NULL,
640
+ `LENGTHVAR` INT(10) DEFAULT '1');"
641
+ MobyUtil::DBAccess.query( db_connection, query_string )
642
+ sql_file.write( query_string + "\n" ) if record_sql
643
+
644
+ query_string = "CREATE UNIQUE INDEX IF NOT EXISTS 'FileLogicNameIndex' ON " + table_name + " (`FNAME`,`LNAME`, `PLURALITY`, `LENGTHVAR`);"
645
+ MobyUtil::DBAccess.query( db_connection, query_string )
646
+ sql_file.write( query_string + "\n" ) if record_sql
647
+
648
+ query_string = "CREATE INDEX IF NOT EXISTS 'FileLogicIndex' ON " + table_name + " (`LNAME`);"
649
+ MobyUtil::DBAccess.query( db_connection, query_string )
650
+ sql_file.write( query_string + "\n" ) if record_sql
651
+ end
652
+
653
+ # ADD NEW COLUMNS for new language if needed
654
+ case db_connection.db_type
655
+ when "mysql"
656
+ begin
657
+ query_string = "ALTER TABLE `" + table_name + "` ADD `" + language + "` TEXT NULL DEFAULT NULL COLLATE utf8_general_ci;"
658
+ MobyUtil::DBAccess.query( db_connection, query_string )
659
+ sql_file.write( query_string + "\n" ) if record_sql
660
+ rescue Mysql::Error # catch if language column already exists
661
+ end
662
+ when "sqlite"
663
+ begin
664
+ query_string = "ALTER TABLE `" + table_name + "` ADD `" + language + "` TEXT;"
665
+ MobyUtil::DBAccess.query( db_connection, query_string )
666
+ sql_file.write( query_string + "\n" ) if record_sql
667
+ rescue SQLite3::SQLException # catch if language column already exists
668
+ end
669
+ end
670
+ # INSERT new data
671
+ case db_connection.db_type
672
+ when "mysql"
673
+ insert_values = ""
674
+
675
+ begin
676
+ # Formatting (seems like there is no length limit for the insert string)
677
+ data.each do |fname, source, translation, plurality, lengthvar|
678
+ # Escape ` and ' and " and other restricted characters in SQL (prevent SQL injections
679
+ source = source.gsub(/([\'\"\`\;\&])/){|s| "\\" + s}
680
+ translation = (translation != nil) ? translation.gsub(/([\'\"\`\;\&\\'\\"])/){|s| "\\" + s} : ""
681
+ if plurality=='NULL'
682
+ insert_values += "('" + fname + "', '" + source + "', '" + translation + "', NULL, '" + lengthvar + "'), "
683
+ else
684
+ insert_values += "('" + fname + "', '" + source + "', '" + translation + "', '" + plurality + "', '" + lengthvar + "'), "
685
+ end
686
+ end
687
+
688
+ insert_values[-2] = ' ' unless insert_values == "" # replace last ',' with ';'
689
+ # INSERT Query
690
+ query_string = "INSERT INTO `" + table_name + "` (FNAME, LNAME, `" + language + "`, `PLURALITY`, `LENGTHVAR`) VALUES " + insert_values +
691
+ "ON DUPLICATE KEY UPDATE fname = VALUES(fname), lname = VALUES(lname), `" + language + "` = VALUES(`" + language + "`) ;"
692
+ MobyUtil::DBAccess.query( db_connection, query_string )
693
+ sql_file.write( query_string + "\n" ) if record_sql
694
+ rescue Exception => e
695
+ puts e.message
696
+ puts e.backtrace
697
+ puts ''
698
+ sql_file.write( "Error: #{e.message}: #{query_string}" + "\n" )
699
+ end
700
+
701
+ when "sqlite"
702
+ begin
703
+ # Formatting (limit on the length of the Insert String! So multiple Insets
704
+ counter = 0
705
+ cumulated = 0
706
+ union_all = ""
707
+ MobyUtil::DBAccess.query( db_connection, "BEGIN TRANSACTION")
708
+ sql_file.write( "BEGIN TRANSACTION\n" ) if record_sql
709
+ data.each do |fname, source, translation, plurality, lengthvar|
710
+ counter += 1
711
+ cumulated += 1
712
+ # we MAYBE fucked if the texts have ";" or "`" or """ but for now only "'" seems to be problematic
713
+ source = source.strip.gsub(/([\'])/){|s| s + s}
714
+ translation = (translation != nil ) ? translation.strip.gsub(/([\'])/){|s| s + s} : ""
715
+ ### UPDATE OR INSERT IF NO ROWS AFFECTED
716
+ query_string = "UPDATE `" + table_name + "` SET `#{language}`='#{translation}' WHERE FNAME='#{fname}' AND " +
717
+ "LNAME='#{source}' AND `PLURALITY`='#{plurality}' AND `LENGTHVAR`='#{lengthvar}';"
718
+ MobyUtil::DBAccess.query( db_connection, query_string )
719
+ sql_file.write( query_string + "\n" ) if record_sql
720
+ if MobyUtil::DBAccess.affected_rows( db_connection ) == 0
721
+ query_string = "INSERT INTO `" + table_name + "` (FNAME, LNAME, `" + language + "`, `PLURALITY`, `LENGTHVAR`) " +
722
+ "VALUES ('#{fname}' ,'#{source}','#{translation}', '#{plurality}', '#{lengthvar}');"
723
+ MobyUtil::DBAccess.query( db_connection, query_string )
724
+ sql_file.write( query_string + "\n" ) if record_sql
725
+ end
726
+ end
727
+ MobyUtil::DBAccess.query( db_connection, "COMMIT TRANSACTION")
728
+ sql_file.write( "COMMIT TRANSACTION\n" ) if record_sql
729
+ rescue Exception => e
730
+ puts e.inspect
731
+ puts e.backtrace.join("\n")
732
+ MobyUtil::DBAccess.query( db_connection, "ROLLBACK TRANSACTION")
733
+ sql_file.write( "ROLLBACK TRANSACTION\n" ) if record_sql
734
+ end
735
+ end
736
+ end
737
+
738
+
739
+ # == description
740
+ # Extracs application name used for FNAME from a given filename (removes language tags and file extension)
741
+ # Used only on .ts files
742
+ def self.parseFName(file)
743
+ #(wordlist matching)
744
+ words = ["ar", "bg", "ca", "cs", "da", "de", "el", "en", "english-gb", "(apac)", "(apaccn)", "(apachk)", "(apactw)", "japanese", "thai", "us", "es", "419", "et", "eu", "fa", "fi", "fr", "gl", "he", "hi", "hr", "hu", "id", "is", "it", "ja", "ko", "lt", "lv", "mr", "ms", "nb", "nl", "pl", "pt", "br", "ro", "ru", "sk", "sl", "sr", "sv", "th", "tl", "tr", "uk", "ur", "us", "vi", "zh", "hk", "tw", "no", "gb", "cn", "kk"]
745
+
746
+ fname = file.split('/').last
747
+ fname.gsub!(".ts"){|s| ""}
748
+ fname_fragments = fname.split('_')
749
+ fname_fragments.each_index do |i|
750
+ fname_fragments[i] = "" if words.include?( fname_fragments[i].downcase )
751
+ end
752
+ fname_fragments.delete("")
753
+ fname = fname_fragments.join("_")
754
+ language = file.split('/').last.gsub( fname + "_" ){|s| ""}.gsub(".ts"){|s| ""}
755
+ return fname, "" if fname == language
756
+ return fname, language
757
+ end
758
+
759
+ end # class
760
+
761
+ end # module
762
+