motiro 0.6.3

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 (309) hide show
  1. data/LICENSE +280 -0
  2. data/README +28 -0
  3. data/README.en +175 -0
  4. data/README.pt-br +175 -0
  5. data/Rakefile +10 -0
  6. data/app/controllers/account_controller.rb +62 -0
  7. data/app/controllers/application.rb +72 -0
  8. data/app/controllers/edition_controller.rb +13 -0
  9. data/app/controllers/javascript_controller.rb +21 -0
  10. data/app/controllers/report_controller.rb +79 -0
  11. data/app/controllers/root_controller.rb +7 -0
  12. data/app/controllers/wiki_controller.rb +102 -0
  13. data/app/core/cache_reporter.rb +53 -0
  14. data/app/core/cache_reporter_fetcher.rb +33 -0
  15. data/app/core/chief_editor.rb +69 -0
  16. data/app/core/reporter.rb +105 -0
  17. data/app/core/reporter_driver.rb +36 -0
  18. data/app/core/reporter_fetcher.rb +39 -0
  19. data/app/core/settings.rb +43 -0
  20. data/app/core/version.rb +1 -0
  21. data/app/core/wiki_page_not_found.rb +33 -0
  22. data/app/core/wiki_reporter.rb +83 -0
  23. data/app/helpers/account_helper.rb +2 -0
  24. data/app/helpers/application_helper.rb +68 -0
  25. data/app/helpers/default_page_provider.rb +28 -0
  26. data/app/helpers/report_helper.rb +2 -0
  27. data/app/helpers/root_helper.rb +2 -0
  28. data/app/helpers/wiki_helper.rb +3 -0
  29. data/app/models/change.rb +96 -0
  30. data/app/models/diff_table_builder.rb +285 -0
  31. data/app/models/event.rb +18 -0
  32. data/app/models/headline.rb +109 -0
  33. data/app/models/page.rb +114 -0
  34. data/app/models/page_sweeper.rb +26 -0
  35. data/app/models/user.rb +85 -0
  36. data/app/ports/chdir_runner.rb +36 -0
  37. data/app/ports/reporter_loader.rb +9 -0
  38. data/app/ports/runner.rb +64 -0
  39. data/app/reporters/darcs_connection.rb +54 -0
  40. data/app/reporters/darcs_reporter.rb +104 -0
  41. data/app/reporters/darcs_settings.rb +9 -0
  42. data/app/reporters/darcs_temp_repo.rb +40 -0
  43. data/app/reporters/events_reporter.rb +28 -0
  44. data/app/reporters/features_reporter.rb +24 -0
  45. data/app/reporters/subversion_reporter.rb +203 -0
  46. data/app/reporters/svn_connection.rb +62 -0
  47. data/app/reporters/svn_settings.rb +40 -0
  48. data/app/views/account/_authorization.rhtml +54 -0
  49. data/app/views/account/_availability.rhtml +5 -0
  50. data/app/views/account/availability.rhtml +1 -0
  51. data/app/views/account/login.rhtml +22 -0
  52. data/app/views/account/logout.rhtml +10 -0
  53. data/app/views/javascript/motiro.rjs +132 -0
  54. data/app/views/javascript/niftycube.rjs +300 -0
  55. data/app/views/layouts/_bottom.rhtml +5 -0
  56. data/app/views/layouts/_header.rhtml +7 -0
  57. data/app/views/layouts/_top.rhtml +25 -0
  58. data/app/views/layouts/application.rhtml +3 -0
  59. data/app/views/layouts/scaffold.rhtml +13 -0
  60. data/app/views/layouts/wiki_edit.rhtml +26 -0
  61. data/app/views/report/list.rhtml +32 -0
  62. data/app/views/report/older.rhtml +26 -0
  63. data/app/views/report/rss.rxml +29 -0
  64. data/app/views/report/show.rhtml +20 -0
  65. data/app/views/root/index.rhtml +33 -0
  66. data/app/views/wiki/_editbar.rhtml +26 -0
  67. data/app/views/wiki/_properties_edit.rhtml +5 -0
  68. data/app/views/wiki/_properties_show.rhtml +5 -0
  69. data/app/views/wiki/edit.rhtml +56 -0
  70. data/app/views/wiki/properties_edit.rhtml +1 -0
  71. data/app/views/wiki/show.rhtml +9 -0
  72. data/bin/motiro +44 -0
  73. data/config/boot.rb +19 -0
  74. data/config/database.yml +14 -0
  75. data/config/environment.rb +64 -0
  76. data/config/environments/development.rb +20 -0
  77. data/config/environments/production.rb +19 -0
  78. data/config/environments/test.rb +19 -0
  79. data/config/motiro.yml +43 -0
  80. data/config/routes.rb +79 -0
  81. data/db/migrate/005_globalize_migration.rb +11363 -0
  82. data/db/migrate/006_remove_headline_title.rb +14 -0
  83. data/db/migrate/007_stretch_rid.rb +11 -0
  84. data/db/migrate/008_add_page_editors.rb +12 -0
  85. data/db/migrate/009_add_page_original_author.rb +12 -0
  86. data/db/migrate/010_remove_empty_string_defaults_from_pages.rb +17 -0
  87. data/db/migrate/011_add_title_and_kind_to_pages.rb +13 -0
  88. data/db/migrate/012_page_modification_info.rb +13 -0
  89. data/db/migrate/013_nullify_initial_page_attributes.rb +21 -0
  90. data/db/migrate/014_events_are_wiki_pages.rb +13 -0
  91. data/db/migrate/015_migrate_previous_event_data.rb +23 -0
  92. data/db/migrate/1_initial_structure.rb +36 -0
  93. data/db/migrate/2_add_authentication.rb +12 -0
  94. data/db/migrate/3_drop_articles.rb +26 -0
  95. data/db/migrate/4_add_page_editing.rb +14 -0
  96. data/db/motirodb.sqlite.initial +0 -0
  97. data/db/schema_version +1 -0
  98. data/db/translation/pt-BR.rb +76 -0
  99. data/doc/README_FOR_APP +2 -0
  100. data/installer/rails_installer_defaults.yml +5 -0
  101. data/lib/import_translations.rb +154 -0
  102. data/lib/login_system.rb +89 -0
  103. data/lib/relative_time.rb +48 -0
  104. data/lib/string_extensions.rb +10 -0
  105. data/lib/stub_hash.rb +22 -0
  106. data/lib/tasks/packaging.rake +93 -0
  107. data/lib/tasks/testing.rake +32 -0
  108. data/lib/tick_daemon.rb +41 -0
  109. data/lib/translator.rb +67 -0
  110. data/lib/wiki_renderer.rb +42 -0
  111. data/lib/wiki_url_generator.rb +29 -0
  112. data/log/.keepdir +0 -0
  113. data/public/404.html +8 -0
  114. data/public/500.html +8 -0
  115. data/public/dispatch.cgi +10 -0
  116. data/public/dispatch.fcgi +24 -0
  117. data/public/dispatch.rb +10 -0
  118. data/public/favicon.ico +0 -0
  119. data/public/images/calendar.png +0 -0
  120. data/public/images/rss.png +0 -0
  121. data/public/javascripts/controls.js +750 -0
  122. data/public/javascripts/dragdrop.js +584 -0
  123. data/public/javascripts/effects.js +854 -0
  124. data/public/javascripts/prototype.js +1785 -0
  125. data/public/robots.txt +1 -0
  126. data/public/stylesheets/motiro.css +269 -0
  127. data/public/stylesheets/niftyCorners.css +35 -0
  128. data/public/stylesheets/scaffold.css +74 -0
  129. data/script/about +3 -0
  130. data/script/breakpointer +3 -0
  131. data/script/console +3 -0
  132. data/script/destroy +3 -0
  133. data/script/generate +3 -0
  134. data/script/performance/benchmarker +3 -0
  135. data/script/performance/profiler +3 -0
  136. data/script/plugin +3 -0
  137. data/script/process/reaper +3 -0
  138. data/script/process/spawner +3 -0
  139. data/script/process/spinner +3 -0
  140. data/script/runner +3 -0
  141. data/script/server +3 -0
  142. data/script/ticker +29 -0
  143. data/test/acceptance/account_test.rb +186 -0
  144. data/test/acceptance/darcs_test.rb +62 -0
  145. data/test/acceptance/events_test.rb +47 -0
  146. data/test/acceptance/main_page_test.rb +92 -0
  147. data/test/acceptance/subversion_test.rb +319 -0
  148. data/test/acceptance/ts_all_suites.rb +27 -0
  149. data/test/acceptance/wiki_test.rb +202 -0
  150. data/test/contract/darcs_test.rb +51 -0
  151. data/test/contract/remote_darcs_test.rb +61 -0
  152. data/test/contract/svn_test.rb +53 -0
  153. data/test/fixtures/changes.yml +25 -0
  154. data/test/fixtures/headlines.yml +45 -0
  155. data/test/fixtures/pages.yml +98 -0
  156. data/test/fixtures/users.yml +31 -0
  157. data/test/functional/account_controller_test.rb +96 -0
  158. data/test/functional/report_controller_test.rb +113 -0
  159. data/test/functional/report_features_test.rb +38 -0
  160. data/test/functional/report_subversion_test.rb +79 -0
  161. data/test/functional/root_controller_test.rb +127 -0
  162. data/test/functional/wiki_controller_test.rb +280 -0
  163. data/test/lib/acceptance_test_case.rb +43 -0
  164. data/test/lib/configuration.rb +53 -0
  165. data/test/lib/darcs_excerpts.rb +181 -0
  166. data/test/lib/darcs_repo.rb +77 -0
  167. data/test/lib/live_mode_test.rb +51 -0
  168. data/test/lib/local_svn.rb +157 -0
  169. data/test/lib/netutils.rb +42 -0
  170. data/test/lib/platform_thread.rb +62 -0
  171. data/test/lib/repoutils.rb +23 -0
  172. data/test/lib/selenium_extensions.rb +32 -0
  173. data/test/lib/stubio.rb +37 -0
  174. data/test/lib/svn_excerpts.rb +288 -0
  175. data/test/lib/test_configuration.rb +14 -0
  176. data/test/lib/webserver.rb +71 -0
  177. data/test/meta/configuration_test.rb +72 -0
  178. data/test/meta/darcs_repo_test.rb +118 -0
  179. data/test/meta/local_svn_test.rb +125 -0
  180. data/test/meta/platform_thread_test.rb +46 -0
  181. data/test/meta/stubio_test.rb +44 -0
  182. data/test/mocks/headline.rb +34 -0
  183. data/test/mocks/svn_reporter.rb +29 -0
  184. data/test/stubs/svn_settings.rb +19 -0
  185. data/test/stubs/url_generator.rb +24 -0
  186. data/test/test_helper.rb +36 -0
  187. data/test/unit/cache_reporter_fetcher_test.rb +46 -0
  188. data/test/unit/cache_reporter_test.rb +97 -0
  189. data/test/unit/caching_test.rb +78 -0
  190. data/test/unit/change_test.rb +152 -0
  191. data/test/unit/chdir_runner_test.rb +77 -0
  192. data/test/unit/chief_editor_test.rb +234 -0
  193. data/test/unit/darcs_connection_test.rb +109 -0
  194. data/test/unit/darcs_reporter_test.rb +146 -0
  195. data/test/unit/darcs_settings_test.rb +37 -0
  196. data/test/unit/darcs_temp_repo_test.rb +51 -0
  197. data/test/unit/default_page_provider_test.rb +46 -0
  198. data/test/unit/diff_table_builder_test.rb +602 -0
  199. data/test/unit/headline_test.rb +259 -0
  200. data/test/unit/page_test.rb +145 -0
  201. data/test/unit/relative_time_test.rb +56 -0
  202. data/test/unit/reporter_driver_test.rb +85 -0
  203. data/test/unit/reporter_fetcher_test.rb +31 -0
  204. data/test/unit/reporter_test.rb +81 -0
  205. data/test/unit/runner_test.rb +93 -0
  206. data/test/unit/settings_test.rb +55 -0
  207. data/test/unit/string_extensions_test.rb +10 -0
  208. data/test/unit/svn_connection_test.rb +183 -0
  209. data/test/unit/svn_reporter_interaction_test.rb +38 -0
  210. data/test/unit/svn_reporter_test.rb +286 -0
  211. data/test/unit/svn_settings_test.rb +86 -0
  212. data/test/unit/translator_test.rb +96 -0
  213. data/test/unit/user_test.rb +125 -0
  214. data/test/unit/wiki_renderer_test.rb +87 -0
  215. data/test/unit/wiki_reporter_test.rb +94 -0
  216. data/test/unit/wiki_url_generator_test.rb +31 -0
  217. data/vendor/motiro-installer.rb +159 -0
  218. data/vendor/plugins/globalize/LICENSE +9 -0
  219. data/vendor/plugins/globalize/README +49 -0
  220. data/vendor/plugins/globalize/data/country_data.csv +240 -0
  221. data/vendor/plugins/globalize/data/language_data.csv +188 -0
  222. data/vendor/plugins/globalize/data/translation_data.csv +3421 -0
  223. data/vendor/plugins/globalize/generators/globalize/USAGE +10 -0
  224. data/vendor/plugins/globalize/generators/globalize/globalize_generator.rb +42 -0
  225. data/vendor/plugins/globalize/generators/globalize/templates/migration.rb.gz +0 -0
  226. data/vendor/plugins/globalize/generators/globalize/templates/tiny_migration.rb.gz +0 -0
  227. data/vendor/plugins/globalize/init.rb +30 -0
  228. data/vendor/plugins/globalize/lib/globalize/localization/core_ext.rb +170 -0
  229. data/vendor/plugins/globalize/lib/globalize/localization/core_ext_hooks.rb +33 -0
  230. data/vendor/plugins/globalize/lib/globalize/localization/db_translate.rb +494 -0
  231. data/vendor/plugins/globalize/lib/globalize/localization/db_view_translator.rb +152 -0
  232. data/vendor/plugins/globalize/lib/globalize/localization/locale.rb +173 -0
  233. data/vendor/plugins/globalize/lib/globalize/localization/rfc_3066.rb +40 -0
  234. data/vendor/plugins/globalize/lib/globalize/models/country.rb +24 -0
  235. data/vendor/plugins/globalize/lib/globalize/models/currency.rb +188 -0
  236. data/vendor/plugins/globalize/lib/globalize/models/language.rb +84 -0
  237. data/vendor/plugins/globalize/lib/globalize/models/model_translation.rb +4 -0
  238. data/vendor/plugins/globalize/lib/globalize/models/translation.rb +9 -0
  239. data/vendor/plugins/globalize/lib/globalize/models/view_translation.rb +14 -0
  240. data/vendor/plugins/globalize/lib/globalize/rails/action_mailer.rb +125 -0
  241. data/vendor/plugins/globalize/lib/globalize/rails/action_view.rb +79 -0
  242. data/vendor/plugins/globalize/lib/globalize/rails/active_record.rb +129 -0
  243. data/vendor/plugins/globalize/lib/globalize/rails/active_record_helper.rb +33 -0
  244. data/vendor/plugins/globalize/populators/pop_dates.rb +81 -0
  245. data/vendor/plugins/globalize/populators/pop_migration.rb +18 -0
  246. data/vendor/plugins/globalize/populators/pop_pluralization.rb +26 -0
  247. data/vendor/plugins/globalize/populators/pop_seps.rb +32 -0
  248. data/vendor/plugins/globalize/tasks/data.rake +130 -0
  249. data/vendor/plugins/globalize/test/action_mailer_test/globalize_mailer/test.en-US.plain.text.rhtml +1 -0
  250. data/vendor/plugins/globalize/test/action_mailer_test/globalize_mailer/test.en.plain.text.rhtml +1 -0
  251. data/vendor/plugins/globalize/test/action_mailer_test/globalize_mailer/test.he.plain.text.rhtml +1 -0
  252. data/vendor/plugins/globalize/test/action_mailer_test/globalize_mailer/test.plain.text.rhtml +1 -0
  253. data/vendor/plugins/globalize/test/action_mailer_test.rb +54 -0
  254. data/vendor/plugins/globalize/test/config/database.yml.default +16 -0
  255. data/vendor/plugins/globalize/test/config/database.yml.example +22 -0
  256. data/vendor/plugins/globalize/test/core_ext_test.rb +61 -0
  257. data/vendor/plugins/globalize/test/currency_test.rb +141 -0
  258. data/vendor/plugins/globalize/test/date_helper_test.rb +634 -0
  259. data/vendor/plugins/globalize/test/db/schema.rb +90 -0
  260. data/vendor/plugins/globalize/test/db_translation_test.rb +374 -0
  261. data/vendor/plugins/globalize/test/fixtures/globalize_categories.yml +7 -0
  262. data/vendor/plugins/globalize/test/fixtures/globalize_categories_products.yml +7 -0
  263. data/vendor/plugins/globalize/test/fixtures/globalize_countries.yml +41 -0
  264. data/vendor/plugins/globalize/test/fixtures/globalize_languages.yml +64 -0
  265. data/vendor/plugins/globalize/test/fixtures/globalize_manufacturers.yml +5 -0
  266. data/vendor/plugins/globalize/test/fixtures/globalize_products.yml +29 -0
  267. data/vendor/plugins/globalize/test/fixtures/globalize_simples.yml +5 -0
  268. data/vendor/plugins/globalize/test/fixtures/globalize_translations.yml +354 -0
  269. data/vendor/plugins/globalize/test/locale_test.rb +27 -0
  270. data/vendor/plugins/globalize/test/mime_responds_test.rb +358 -0
  271. data/vendor/plugins/globalize/test/model_test.rb +17 -0
  272. data/vendor/plugins/globalize/test/standard_data_test_helper.rb +33 -0
  273. data/vendor/plugins/globalize/test/test_helper.rb +19 -0
  274. data/vendor/plugins/globalize/test/test_standard_data.rb +54 -0
  275. data/vendor/plugins/globalize/test/validation_test.rb +29 -0
  276. data/vendor/plugins/globalize/test/view_picking_test.rb +49 -0
  277. data/vendor/plugins/globalize/test/view_translation_test.rb +237 -0
  278. data/vendor/plugins/globalize/test/views/layouts/standard.rhtml +1 -0
  279. data/vendor/plugins/globalize/test/views/respond_to/all_types_with_layout.rhtml +1 -0
  280. data/vendor/plugins/globalize/test/views/respond_to/all_types_with_layout.rjs +1 -0
  281. data/vendor/plugins/globalize/test/views/respond_to/using_defaults.en.rhtml +1 -0
  282. data/vendor/plugins/globalize/test/views/respond_to/using_defaults.en.rjs +1 -0
  283. data/vendor/plugins/globalize/test/views/respond_to/using_defaults.en.rxml +1 -0
  284. data/vendor/plugins/globalize/test/views/respond_to/using_defaults.fr.rhtml +1 -0
  285. data/vendor/plugins/globalize/test/views/respond_to/using_defaults.fr.rjs +1 -0
  286. data/vendor/plugins/globalize/test/views/respond_to/using_defaults.fr.rxml +1 -0
  287. data/vendor/plugins/globalize/test/views/respond_to/using_defaults.rhtml +1 -0
  288. data/vendor/plugins/globalize/test/views/respond_to/using_defaults.rjs +1 -0
  289. data/vendor/plugins/globalize/test/views/respond_to/using_defaults.rxml +1 -0
  290. data/vendor/plugins/globalize/test/views/respond_to/using_defaults_with_type_list.en.rhtml +1 -0
  291. data/vendor/plugins/globalize/test/views/respond_to/using_defaults_with_type_list.en.rjs +1 -0
  292. data/vendor/plugins/globalize/test/views/respond_to/using_defaults_with_type_list.en.rxml +1 -0
  293. data/vendor/plugins/globalize/test/views/respond_to/using_defaults_with_type_list.fr.rhtml +1 -0
  294. data/vendor/plugins/globalize/test/views/respond_to/using_defaults_with_type_list.fr.rjs +1 -0
  295. data/vendor/plugins/globalize/test/views/respond_to/using_defaults_with_type_list.fr.rxml +1 -0
  296. data/vendor/plugins/globalize/test/views/respond_to/using_defaults_with_type_list.rhtml +1 -0
  297. data/vendor/plugins/globalize/test/views/respond_to/using_defaults_with_type_list.rjs +1 -0
  298. data/vendor/plugins/globalize/test/views/respond_to/using_defaults_with_type_list.rxml +1 -0
  299. data/vendor/plugins/globalize/test/views/test.he-IL.rhtml +1 -0
  300. data/vendor/plugins/globalize/test/views/test.rhtml +1 -0
  301. data/vendor/plugins/globalize/test/views/test2.he.rhtml +1 -0
  302. data/vendor/plugins/globalize/test/views/test2.rhtml +1 -0
  303. data/vendor/plugins/test_xml/MIT-LICENSE +20 -0
  304. data/vendor/plugins/test_xml/README +20 -0
  305. data/vendor/plugins/test_xml/Rakefile +22 -0
  306. data/vendor/plugins/test_xml/init.rb +7 -0
  307. data/vendor/plugins/test_xml/lib/xml_assertions.rb +22 -0
  308. data/vendor/plugins/test_xml/test/test_xml_test.rb +40 -0
  309. metadata +505 -0
@@ -0,0 +1,28 @@
1
+ # Motiro - A project tracking tool
2
+ # Copyright (C) 2006-2007 Thiago Arrais
3
+ #
4
+ # This program is free software; you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation; either version 2 of the License, or
7
+ # any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program; if not, write to the Free Software
16
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17
+
18
+ require 'core/wiki_reporter'
19
+
20
+ class EventsReporter < WikiReporter
21
+
22
+ title 'Scheduled events'
23
+
24
+ def column; 'happens_at'; end
25
+
26
+ def extract_happened_at(page); page.happens_at.to_t; end
27
+
28
+ end
@@ -0,0 +1,24 @@
1
+ # Motiro - A project tracking tool
2
+ # Copyright (C) 2006-2007 Thiago Arrais
3
+ #
4
+ # This program is free software; you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation; either version 2 of the License, or
7
+ # any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program; if not, write to the Free Software
16
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17
+
18
+ require 'core/wiki_reporter'
19
+
20
+ class FeaturesReporter < WikiReporter
21
+
22
+ title 'Recently changed suggestions'
23
+
24
+ end
@@ -0,0 +1,203 @@
1
+ # Motiro - A project tracking tool
2
+ # Copyright (C) 2006-2007 Thiago Arrais
3
+ #
4
+ # This program is free software; you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation; either version 2 of the License, or
7
+ # any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program; if not, write to the Free Software
16
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17
+
18
+ require 'rexml/rexml'
19
+
20
+ require 'reporters/svn_connection'
21
+ require 'models/headline'
22
+ require 'core/reporter'
23
+
24
+ class String
25
+
26
+ def to_rev_num
27
+ self.match(/\d+/)[0]
28
+ end
29
+
30
+ end
31
+
32
+ class SubversionReporter < MotiroReporter
33
+
34
+ def initialize(connection = SubversionConnection.new)
35
+ @connection = connection
36
+ end
37
+
38
+ def latest_headlines(from_rid=nil)
39
+ from_rid ||= 'r0'
40
+ build_headlines_from(@connection.log(:history_from => from_rid))
41
+ end
42
+
43
+ def headlines
44
+ build_headlines_from(@connection.log(:all))
45
+ end
46
+
47
+ def headline(rid)
48
+ revision_id = rid.match(/^r(.+)/)[1]
49
+
50
+ output = @connection.log(:only => revision_id)
51
+
52
+ result_headline, remain = build_headline_from(output)
53
+
54
+ return result_headline
55
+ end
56
+
57
+ private
58
+
59
+ def build_headlines_from(text)
60
+ remain = text
61
+ hls = Array.new
62
+
63
+ hl = 0
64
+ until hl.nil? do
65
+ hl, remain = build_headline_from(remain)
66
+ unless hl.nil?
67
+ hl.reported_by = self.name
68
+ hls.push hl
69
+ end
70
+ end
71
+ return hls
72
+ end
73
+
74
+ def build_headline_from(text)
75
+ begin
76
+ result = Headline.new
77
+
78
+ result, remain = consume_dashes(result, text)
79
+ result, remain = parse_header(result, remain)
80
+ result, remain = parse_changed_resources(result, remain)
81
+ result, remain = parse_description(result, remain)
82
+
83
+ return result, remain
84
+ rescue
85
+ return nil
86
+ end
87
+ end
88
+
89
+ def consume_dashes(theHeadline, text)
90
+ remain = /^-+\n/.match(text).post_match
91
+ return theHeadline, remain
92
+ end
93
+
94
+ def parse_header(theHeadline, text)
95
+ md = text.match /^(r\d+)\s*\|\s*(\w+)\s*\|\s(\d+)-(\d+)-(\d+)\s+(\d+):(\d+):(\d+)[^|]*\|\s*(\d+)\s*[^\n]*\n/
96
+ remain = md.post_match
97
+
98
+ theHeadline.rid = md[1]
99
+ theHeadline.author = md[2]
100
+ theHeadline.happened_at = md[3..8].collect do |s| s.to_i end
101
+
102
+ return theHeadline, remain
103
+ end
104
+
105
+ def parse_changed_resources(theHeadline, text)
106
+ remain = text
107
+
108
+ changes = theHeadline.changes
109
+
110
+ # skip the first line with the title 'Changed resources' (or something
111
+ # like this)
112
+ remain = remain.match(/\n/).post_match
113
+
114
+ md = remain.match(/^\n/)
115
+ resources = md.pre_match
116
+ remain = md.post_match
117
+
118
+ while('' != resources) do
119
+ md = resources.match(/\n/)
120
+ resources = md.post_match
121
+
122
+ summary = md.pre_match
123
+ resource_path = summary.match(/\w ([^\s]+)/)[1]
124
+ diff = diff_for(resource_path, theHeadline.rid)
125
+ kind = kind_of(resource_path, theHeadline.rid)
126
+ changes.push(Change.new(:summary => summary,
127
+ :resource_kind => kind,
128
+ :diff => diff))
129
+ end
130
+
131
+ return theHeadline, remain
132
+ end
133
+
134
+ def diff_for(resource_path, revision_id)
135
+ revision_num = revision_id.to_rev_num
136
+
137
+ remain = @connection.diff(revision_num)
138
+
139
+ while(md = remain.match(/^Index: ([^\n]+)$/)) do
140
+ remain = md.post_match
141
+ if resource_path.include?(md[1])
142
+ diff_text = md[0]
143
+ if (md = remain.match(/^Index:/))
144
+ diff_text += md.pre_match
145
+ else
146
+ diff_text += remain
147
+ end
148
+ return svn_parse_diff(diff_text)
149
+ end
150
+ end
151
+ end
152
+
153
+ def kind_of(resource_path, revision_id)
154
+ revision_num = revision_id.to_rev_num
155
+
156
+ begin
157
+ raw_info = @connection.info(resource_path, revision_num)
158
+ info = REXML::Document.new(raw_info).root
159
+
160
+ return info.elements['entry'].attributes['kind']
161
+ rescue
162
+ return nil
163
+ end
164
+ end
165
+
166
+ def svn_parse_diff(text)
167
+ remain = text
168
+ md = text.match(/Index: [^\n]+$/)
169
+ remain = md.post_match
170
+
171
+ 1.upto 4 do
172
+ remain = /\n/.match(remain).post_match
173
+ end
174
+
175
+ if (md = remain.match(/^Index:/))
176
+ return md.pre_match
177
+ else
178
+ return remain
179
+ end
180
+ end
181
+
182
+ def parse_description(theHeadline, text)
183
+ md = /\n-+\n/.match(text)
184
+ theHeadline.description = md.pre_match
185
+
186
+ remain = md[0] + md.post_match
187
+
188
+ return theHeadline, remain
189
+ end
190
+
191
+ # consumes lines until a line matching the given regexp is found
192
+ def consume_until(regexp, text)
193
+ theRegexp = Regexp.new("^#{regexp}\n")
194
+ remain = text
195
+
196
+ while(!remain.match(theRegexp)) do
197
+ remain = remain.match(/\n/.post_match)
198
+ end
199
+
200
+ return remain
201
+ end
202
+
203
+ end
@@ -0,0 +1,62 @@
1
+ # Motiro - A project tracking tool
2
+ # Copyright (C) 2006-2007 Thiago Arrais
3
+ #
4
+ # This program is free software; you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation; either version 2 of the License, or
7
+ # any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program; if not, write to the Free Software
16
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17
+
18
+ require 'ports/runner'
19
+ require 'reporters/svn_settings'
20
+
21
+ class SubversionConnection
22
+
23
+ def initialize(settings=SubversionSettingsProvider.new, runner=Runner.new)
24
+ @settings = settings
25
+ @runner = FixedParameterRunner.new(runner, "t\n", 'LC_MESSAGES' => 'C')
26
+ @diff_cache = Hash.new
27
+ end
28
+
29
+ def log(options={:history_from => 'r0'})
30
+ command = "log #{@settings.repo_url} -v"
31
+
32
+ if options.respond_to? :[]
33
+ if options[:history_from]
34
+ r = options[:history_from]
35
+ command += " -rHEAD:#{r[1..r.length].succ} --limit=#{@settings.package_size}"
36
+ elsif options[:only]
37
+ command += " -r#{options[:only].to_s}"
38
+ end
39
+ end
40
+
41
+ svn(command)
42
+ end
43
+
44
+ def diff(rev_id)
45
+ @diff_cache[rev_id] ||= svn("diff #{@settings.repo_url} -r#{rev_id.to_i - 1}:#{rev_id}")
46
+ end
47
+
48
+ def info(path, rev_id)
49
+ svn("info -r#{rev_id} --xml #{@settings.repo_url}#{path}")
50
+ end
51
+
52
+ private
53
+
54
+ def svn(command)
55
+ credentials = @settings.repo_user ?
56
+ "--username='#{@settings.repo_user}' --password='#{@settings.repo_password}' " :
57
+ ''
58
+
59
+ @runner.run("svn " + credentials + command)
60
+ end
61
+
62
+ end
@@ -0,0 +1,40 @@
1
+ # Motiro - A project tracking tool
2
+ # Copyright (C) 2006-2007 Thiago Arrais
3
+ #
4
+ # This program is free software; you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation; either version 2 of the License, or
7
+ # any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program; if not, write to the Free Software
16
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17
+
18
+ require 'core/settings'
19
+
20
+ class SubversionSettingsProvider < SettingsProvider
21
+
22
+ def repo_url
23
+ subversion['repo']
24
+ end
25
+
26
+ def repo_user
27
+ subversion['user']
28
+ end
29
+
30
+ def repo_password
31
+ subversion['password']
32
+ end
33
+
34
+ private
35
+
36
+ def subversion
37
+ load_confs['subversion']
38
+ end
39
+
40
+ end
@@ -0,0 +1,54 @@
1
+ <% if current_user.nil? then %>
2
+ <div id="authentication_errors">
3
+ <%= render :partial => 'account/availability' %>
4
+ </div>
5
+ <%= content_tag :span, 'Passwords do not match'.t,
6
+ :id => 'passwords_do_not_match', :class => 'warning',
7
+ :style=> 'display:none' %>
8
+ <% form_tag :controller => 'account', :action=> 'login' do %>
9
+ <div class="authorization_cell">
10
+ <%= content_tag :label, 'User'.t, :for=> 'user_login'%><br />
11
+ <%= text_field 'user', 'login', :size => 12,
12
+ :value => flash[:desired_login] %>
13
+ </div>
14
+ <div class="authorization_cell">
15
+ <%= content_tag :label, 'Password'.t, :for=> 'user_password'%><br />
16
+ <%= password_field 'user', 'password', :size => 12 %>
17
+ </div>
18
+ <div id="password_confirm" class="authorization_cell" style="display: none;">
19
+ <%= content_tag :label, 'Confirmation'.t, :for=> 'user_password_confirmation'%>
20
+ <%= password_field 'user', 'password_confirmation',
21
+ :size => 12,
22
+ :disabled => true %>
23
+ </div>
24
+ <div class="authorization_cell">
25
+ <input type="checkbox" id="chk_new_user"
26
+ name="chk_new_user" class="checkbox"
27
+ onClick="tooglePasswordConfirmation(document.forms[0].chk_new_user.checked)" />
28
+ <%= 'New user?'.t %><br />
29
+ <input type='hidden' name='return_to' value="<%= request.env['REQUEST_URI'] -%>"/>
30
+ <input class='button' type="submit" name="login" value="Login &#187;" />
31
+ </div>
32
+ <% if flash[:login_failure] %>
33
+ <%= content_tag(:span,
34
+ 'Incorrect username or password. Please try again.'.t,
35
+ :class => 'warning') -%>
36
+ <% end %>
37
+ <%= observe_field 'user_login',
38
+ :function => "if (document.getElementById('chk_new_user').checked) { new Ajax.Updater('authentication_errors', '#{url_for :controller => 'account', :action => 'availability'}', {asynchronous:true, evalScripts:true, parameters:'desired_login=' + value})}",
39
+ :with => 'desired_login',
40
+ :frequency => 1,
41
+ :update => 'authentication_errors' %>
42
+ <% ['user_password', 'user_password_confirmation'].each do |field| %>
43
+ <%= observe_field field, :frequency => 1,
44
+ :function => "check_password_confirmation()" %>
45
+ <% end%>
46
+ <% end %>
47
+ <% else %>
48
+ <%= 'Welcome'.t -%>, <%= current_user.login -%>
49
+ [<%= link_to 'Sign out'.t,
50
+ { :controller => 'account',
51
+ :action => 'logout',
52
+ :return_to => request.env['REQUEST_URI'] },
53
+ :id => 'signout' -%>]
54
+ <% end %>
@@ -0,0 +1,5 @@
1
+ <% if @login_not_available %>
2
+ <span class="warning" id="username_not_available"><%= 'Not available'.t -%></span>
3
+ <% else %>
4
+ <span style="position: absolute" />
5
+ <% end %>
@@ -0,0 +1 @@
1
+ <%= render :partial => 'availability' %>
@@ -0,0 +1,22 @@
1
+ <% form_tag(:action=> "login") do %>
2
+
3
+ <div title="Account login" id="loginform" class="form">
4
+ <h3>Please login</h3>
5
+
6
+ <% if flash['notice'] %>
7
+ <div id="message"><%= flash['notice'] %></div>
8
+ <% end %>
9
+
10
+ <label for="user_login">Login:</label><br/>
11
+ <input type="text" name="user_login" id="user_login" size="30" value=""/><br/>
12
+
13
+ <label for="user_password">Senha:</label><br/>
14
+ <input type="password" name="user_password" id="user_password" size="30"/>
15
+
16
+ <br/>
17
+ <input type="submit" name="login" value="Login &#187;" class="primary" />
18
+
19
+ </div>
20
+
21
+ <% end %>
22
+
@@ -0,0 +1,10 @@
1
+
2
+ <div class="memo">
3
+ <h3>Logoff</h3>
4
+
5
+ <p>Você não está mais no sistema...</p>
6
+
7
+ <%= link_to "&#171; login", :action=>"login"%>
8
+
9
+ </div>
10
+
@@ -0,0 +1,132 @@
1
+ page << <<JS
2
+ function showOnly(divId) {
3
+ document.getElementById('changes').style.display = 'block';
4
+
5
+ var diffs = getElementsBySelector("div.diff-window")
6
+
7
+ for(i=0; i < diffs.length; i++) {
8
+ diffs[i].style.display = 'none'
9
+ }
10
+
11
+ var div = document.getElementById(divId);
12
+ if(div) {
13
+ div.style.display = 'block';
14
+ }
15
+ }
16
+
17
+ function submitButtons() {
18
+ return new Array(document.getElementById("btnSave"),
19
+ document.getElementById("btnDiscard"));
20
+ }
21
+
22
+ function disableSubmit() {
23
+ var btns = submitButtons();
24
+ for(i=0; i < btns.length; i++) {
25
+ btns[i].disabled = true;
26
+ btns[i].oldColor = btns[i].style.color;
27
+ btns[i].style.color = '#90c0e0';
28
+ }
29
+ }
30
+
31
+ function enableSubmit() {
32
+ var btns = submitButtons();
33
+ for(i=0; i < btns.length; i++) {
34
+ btns[i].disabled = false;
35
+ btns[i].style.color = btns[i].oldColor;
36
+ }
37
+ }
38
+
39
+ function loadingNotice() {
40
+ return document.getElementById("loading");
41
+ }
42
+
43
+ function extraPropertiesLoading() {
44
+ disableSubmit();
45
+ loadingNotice().style.display = 'block';
46
+ }
47
+
48
+ function extraPropertiesLoaded() {
49
+ enableSubmit();
50
+ loadingNotice().style.display = 'none';
51
+ }
52
+
53
+ function tooglePasswordConfirmation(show) {
54
+ var elem = document.getElementById('password_confirm');
55
+ var state = show ? 'block' : 'none';
56
+ var action = show ? '#{url_for :controller => 'account', :action => 'signup'}' : '#{url_for :controller => 'account', :action => 'login'}' ;
57
+
58
+ document.getElementById("user_password_confirmation").disabled = !show;
59
+ document.forms[0].action = action;
60
+
61
+ elem.style.display = state;
62
+ }
63
+
64
+ function check_password_confirmation() {
65
+ var passwd = document.getElementById('user_password').value;
66
+ var passwd_confirm = document.getElementById('user_password_confirmation').value;
67
+ var do_not_match_warn = document.getElementById('passwords_do_not_match');
68
+
69
+ if (passwd_confirm == '' || passwd == '' || passwd == passwd_confirm) {
70
+ do_not_match_warn.style.display = 'none';
71
+ } else {
72
+ do_not_match_warn.style.display = 'block';
73
+ }
74
+ }
75
+
76
+ //copied from niftycube
77
+ //TODO try to DRY this
78
+ function getElementsBySelector(selector){
79
+ var i,j,selid="",selclass="",tag=selector,tag2="",v2,k,f,a,s=[],objlist=[],c;
80
+ if(selector.find("#")){ //id selector like "tag#id"
81
+ if(selector.find(" ")){ //descendant selector like "tag#id tag"
82
+ s=selector.split(" ");
83
+ var fs=s[0].split("#");
84
+ if(fs.length==1) return(objlist);
85
+ f=document.getElementById(fs[1]);
86
+ if(f){
87
+ v=f.getElementsByTagName(s[1]);
88
+ for(i=0;i<v.length;i++) objlist.push(v[i]);
89
+ }
90
+ return(objlist);
91
+ }
92
+ else{
93
+ s=selector.split("#");
94
+ tag=s[0];
95
+ selid=s[1];
96
+ if(selid!=""){
97
+ f=document.getElementById(selid);
98
+ if(f) objlist.push(f);
99
+ return(objlist);
100
+ }
101
+ }
102
+ }
103
+ if(selector.find(".")){ //class selector like "tag.class"
104
+ s=selector.split(".");
105
+ tag=s[0];
106
+ selclass=s[1];
107
+ if(selclass.find(" ")){ //descendant selector like tag1.classname tag2
108
+ s=selclass.split(" ");
109
+ selclass=s[0];
110
+ tag2=s[1];
111
+ }
112
+ }
113
+ var v=document.getElementsByTagName(tag); // tag selector like "tag"
114
+ if(selclass==""){
115
+ for(i=0;i<v.length;i++) objlist.push(v[i]);
116
+ return(objlist);
117
+ }
118
+ for(i=0;i<v.length;i++){
119
+ c=v[i].className.split(" ");
120
+ for(j=0;j<c.length;j++){
121
+ if(c[j]==selclass){
122
+ if(tag2=="") objlist.push(v[i]);
123
+ else{
124
+ v2=v[i].getElementsByTagName(tag2);
125
+ for(k=0;k<v2.length;k++) objlist.push(v2[k]);
126
+ }
127
+ }
128
+ }
129
+ }
130
+ return(objlist);
131
+ }
132
+ JS