xiki 0.5.0a

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 (252) hide show
  1. data/Gemfile +11 -0
  2. data/LICENSE +22 -0
  3. data/README.markdown +83 -0
  4. data/Rakefile +8 -0
  5. data/bin/xiki +46 -0
  6. data/etc/command/xiki_command.rb +203 -0
  7. data/etc/command/xiki_process.rb +52 -0
  8. data/etc/command/xiki_wrapper +2 -0
  9. data/etc/js/menu1.js +55 -0
  10. data/etc/js/xiki.js +259 -0
  11. data/etc/logo.png +0 -0
  12. data/etc/presentations/bootstrap.deck +5 -0
  13. data/etc/presentations/databases.deck +41 -0
  14. data/etc/presentations/diffs.deck +23 -0
  15. data/etc/presentations/documentation.deck +14 -0
  16. data/etc/presentations/effects.deck +5 -0
  17. data/etc/presentations/face.deck +297 -0
  18. data/etc/presentations/files.deck +79 -0
  19. data/etc/presentations/icons.deck +22 -0
  20. data/etc/presentations/images.deck +24 -0
  21. data/etc/presentations/key_shortcuts.deck +16 -0
  22. data/etc/presentations/macros.deck +18 -0
  23. data/etc/presentations/menu_classes.deck +44 -0
  24. data/etc/presentations/menu_directories.deck +30 -0
  25. data/etc/presentations/notes.deck +19 -0
  26. data/etc/presentations/other_languages.deck +55 -0
  27. data/etc/presentations/other_wiki_syntaxes.deck +4 -0
  28. data/etc/presentations/piano.deck +5 -0
  29. data/etc/presentations/potential/diffs.deck +38 -0
  30. data/etc/presentations/potential/evolution.deck +18 -0
  31. data/etc/presentations/potential/intro.deck +711 -0
  32. data/etc/presentations/potential/intro1.deck +711 -0
  33. data/etc/presentations/potential/intro2.deck +97 -0
  34. data/etc/presentations/potential/make_mysql_menu.deck +36 -0
  35. data/etc/presentations/potential/ruby_development.deck +17 -0
  36. data/etc/presentations/potential/ui_prototyping.deck +50 -0
  37. data/etc/presentations/potential/web_dev.deck +4 -0
  38. data/etc/presentations/potential/web_development.deck +10 -0
  39. data/etc/presentations/potential/wiki.deck +45 -0
  40. data/etc/presentations/presentations.deck +24 -0
  41. data/etc/presentations/rails_development.deck +29 -0
  42. data/etc/presentations/search_key_shortcuts.deck +37 -0
  43. data/etc/presentations/simplest_possible_ui.deck +37 -0
  44. data/etc/presentations/svg.deck +5 -0
  45. data/etc/presentations/testing.deck +28 -0
  46. data/etc/presentations/the_end.deck +13 -0
  47. data/etc/presentations/type_something_and_double_click.deck +57 -0
  48. data/etc/presentations/type_the_acronym.deck +144 -0
  49. data/etc/presentations/web_browser.deck +56 -0
  50. data/etc/presentations/xiki_command.deck +20 -0
  51. data/etc/presentations/xiki_url.deck +14 -0
  52. data/etc/shark.icns +0 -0
  53. data/etc/shark_script.icns +0 -0
  54. data/etc/snippets/html.notes +7 -0
  55. data/etc/snippets/notes.notes +20 -0
  56. data/etc/snippets/rb.notes +38 -0
  57. data/etc/templates/menu_template.menu +2 -0
  58. data/etc/templates/menu_template.rb +8 -0
  59. data/etc/templates/template.rb +5 -0
  60. data/etc/themes/Dark_Metal.notes +28 -0
  61. data/etc/themes/Orange_Path.notes +15 -0
  62. data/etc/themes/Shiny_Blue.notes +27 -0
  63. data/etc/themes/Shiny_Green.notes +27 -0
  64. data/etc/wrappers/wrapper.js +17 -0
  65. data/etc/wrappers/wrapper.py +20 -0
  66. data/etc/wrappers/wrapper.rb +25 -0
  67. data/lib/block.rb +72 -0
  68. data/lib/bookmarks.rb +352 -0
  69. data/lib/buffers.rb +170 -0
  70. data/lib/clipboard.rb +333 -0
  71. data/lib/code.rb +860 -0
  72. data/lib/code_tree.rb +476 -0
  73. data/lib/color.rb +274 -0
  74. data/lib/console.rb +557 -0
  75. data/lib/control_lock.rb +9 -0
  76. data/lib/control_tab.rb +176 -0
  77. data/lib/core_ext.rb +31 -0
  78. data/lib/cursor.rb +111 -0
  79. data/lib/deletes.rb +65 -0
  80. data/lib/diff_log.rb +297 -0
  81. data/lib/effects.rb +145 -0
  82. data/lib/environment.rb +5 -0
  83. data/lib/file_tree.rb +1875 -0
  84. data/lib/files.rb +334 -0
  85. data/lib/hide.rb +259 -0
  86. data/lib/history.rb +286 -0
  87. data/lib/image.rb +51 -0
  88. data/lib/incrementer.rb +15 -0
  89. data/lib/insert.rb +7 -0
  90. data/lib/irc.rb +22 -0
  91. data/lib/key_bindings.rb +658 -0
  92. data/lib/keys.rb +754 -0
  93. data/lib/launcher.rb +1351 -0
  94. data/lib/line.rb +429 -0
  95. data/lib/links.rb +6 -0
  96. data/lib/location.rb +175 -0
  97. data/lib/macros.rb +48 -0
  98. data/lib/man.rb +19 -0
  99. data/lib/menu.rb +708 -0
  100. data/lib/merb.rb +259 -0
  101. data/lib/message.rb +5 -0
  102. data/lib/meths.rb +56 -0
  103. data/lib/mode.rb +34 -0
  104. data/lib/move.rb +248 -0
  105. data/lib/notes.rb +1000 -0
  106. data/lib/numbers.rb +45 -0
  107. data/lib/ol.rb +203 -0
  108. data/lib/ol_helper.rb +44 -0
  109. data/lib/overlay.rb +167 -0
  110. data/lib/pause_means_space.rb +68 -0
  111. data/lib/php.rb +22 -0
  112. data/lib/projects.rb +21 -0
  113. data/lib/relinquish_exception.rb +2 -0
  114. data/lib/remote.rb +206 -0
  115. data/lib/requirer.rb +46 -0
  116. data/lib/rest_tree.rb +108 -0
  117. data/lib/ruby.rb +57 -0
  118. data/lib/ruby_console.rb +165 -0
  119. data/lib/search.rb +1572 -0
  120. data/lib/search_term.rb +40 -0
  121. data/lib/snippet.rb +68 -0
  122. data/lib/specs.rb +229 -0
  123. data/lib/styles.rb +274 -0
  124. data/lib/svn.rb +682 -0
  125. data/lib/text_util.rb +110 -0
  126. data/lib/tree.rb +1871 -0
  127. data/lib/tree_cursor.rb +87 -0
  128. data/lib/trouble_shooting.rb +27 -0
  129. data/lib/url_tree.rb +11 -0
  130. data/lib/view.rb +1474 -0
  131. data/lib/window.rb +133 -0
  132. data/lib/xiki.rb +404 -0
  133. data/menus/accounts.rb +5 -0
  134. data/menus/address_book.rb +21 -0
  135. data/menus/agenda.rb +28 -0
  136. data/menus/all.rb +5 -0
  137. data/menus/amazon.rb +16 -0
  138. data/menus/app.rb +16 -0
  139. data/menus/applescript.rb +46 -0
  140. data/menus/as.rb +15 -0
  141. data/menus/bookmarklet.rb +63 -0
  142. data/menus/bootstrap.rb +568 -0
  143. data/menus/browse.rb +13 -0
  144. data/menus/browser.rb +78 -0
  145. data/menus/cassandra_db.rb +36 -0
  146. data/menus/chmod.rb +27 -0
  147. data/menus/classes.rb +5 -0
  148. data/menus/coffee_script.rb +35 -0
  149. data/menus/computer.rb +24 -0
  150. data/menus/contacts.rb +5 -0
  151. data/menus/cookies.rb +25 -0
  152. data/menus/couch.rb +184 -0
  153. data/menus/crop.rb +45 -0
  154. data/menus/css.rb +55 -0
  155. data/menus/current.rb +5 -0
  156. data/menus/db.rb +12 -0
  157. data/menus/deck.rb +219 -0
  158. data/menus/dictionary.rb +9 -0
  159. data/menus/dir.rb +8 -0
  160. data/menus/disk.rb +5 -0
  161. data/menus/do.rb +13 -0
  162. data/menus/docs.rb +58 -0
  163. data/menus/dotsies.rb +107 -0
  164. data/menus/edited.rb +18 -0
  165. data/menus/emacs.rb +17 -0
  166. data/menus/enter.rb +13 -0
  167. data/menus/eval.rb +17 -0
  168. data/menus/executable.rb +16 -0
  169. data/menus/filter.rb +46 -0
  170. data/menus/firefox.rb +607 -0
  171. data/menus/foo.rb +30 -0
  172. data/menus/french.rb +7 -0
  173. data/menus/git.rb +185 -0
  174. data/menus/gito.rb +785 -0
  175. data/menus/google.rb +35 -0
  176. data/menus/google_images.rb +11 -0
  177. data/menus/google_patents.rb +10 -0
  178. data/menus/gutenberg.rb +13 -0
  179. data/menus/head.rb +10 -0
  180. data/menus/headings.rb +39 -0
  181. data/menus/html.rb +61 -0
  182. data/menus/icon.rb +40 -0
  183. data/menus/images.menu +2 -0
  184. data/menus/img.rb +15 -0
  185. data/menus/info.rb +9 -0
  186. data/menus/ip.rb +10 -0
  187. data/menus/iterm.rb +36 -0
  188. data/menus/itunes.rb +78 -0
  189. data/menus/javascript.rb +74 -0
  190. data/menus/layout.rb +18 -0
  191. data/menus/local_storage.rb +67 -0
  192. data/menus/ls.rb +19 -0
  193. data/menus/mac.rb +87 -0
  194. data/menus/maps.rb +18 -0
  195. data/menus/matches.rb +18 -0
  196. data/menus/memcache.rb +117 -0
  197. data/menus/mkdir.rb +23 -0
  198. data/menus/mongo.rb +83 -0
  199. data/menus/mysql.rb +294 -0
  200. data/menus/node.rb +88 -0
  201. data/menus/open.rb +19 -0
  202. data/menus/outline.rb +24 -0
  203. data/menus/piano.rb +746 -0
  204. data/menus/postgres.rb +34 -0
  205. data/menus/pre.rb +5 -0
  206. data/menus/python.rb +39 -0
  207. data/menus/rails.rb +160 -0
  208. data/menus/rake.rb +12 -0
  209. data/menus/redmine.rb +168 -0
  210. data/menus/riak_tree.rb +204 -0
  211. data/menus/rss.rb +15 -0
  212. data/menus/safari.rb +11 -0
  213. data/menus/sass.rb +15 -0
  214. data/menus/say.rb +6 -0
  215. data/menus/scale.rb +49 -0
  216. data/menus/serve.rb +78 -0
  217. data/menus/shuffle.rb +24 -0
  218. data/menus/spanish.rb +7 -0
  219. data/menus/standalone.rb +57 -0
  220. data/menus/tail.rb +41 -0
  221. data/menus/technologies.rb +19 -0
  222. data/menus/themes.rb +32 -0
  223. data/menus/thesaurus.rb +13 -0
  224. data/menus/to.rb +24 -0
  225. data/menus/twitter.rb +57 -0
  226. data/menus/wikipedia.rb +34 -0
  227. data/menus/words.rb +11 -0
  228. data/spec/code_tree_spec.rb +59 -0
  229. data/spec/diff_log_spec.rb +40 -0
  230. data/spec/file_tree_spec.rb +102 -0
  231. data/spec/keys_spec.rb +24 -0
  232. data/spec/line_spec.rb +68 -0
  233. data/spec/menu_spec.rb +50 -0
  234. data/spec/ol_spec.rb +98 -0
  235. data/spec/remote_spec.rb +43 -0
  236. data/spec/search_spec.rb +162 -0
  237. data/spec/text_util_spec.rb +119 -0
  238. data/spec/tree_cursor_spec.rb +91 -0
  239. data/spec/tree_spec.rb +955 -0
  240. data/tests/console_test.rb +11 -0
  241. data/tests/couch_db_test.rb +12 -0
  242. data/tests/diff_log_test.rb +43 -0
  243. data/tests/el_mixin.rb +16 -0
  244. data/tests/git_test.rb +95 -0
  245. data/tests/keys_test.rb +19 -0
  246. data/tests/line_test.rb +38 -0
  247. data/tests/merb_test.rb +11 -0
  248. data/tests/redmine_test.rb +50 -0
  249. data/tests/remote_test.rb +31 -0
  250. data/tests/rest_tree_test.rb +70 -0
  251. data/xiki.gemspec +37 -0
  252. metadata +332 -0
@@ -0,0 +1,34 @@
1
+ class Postgres
2
+
3
+ def self.name= name
4
+ @@name = name
5
+ end
6
+
7
+ def self.menu name=nil
8
+
9
+ # If no name, list all names
10
+ if name.nil?
11
+ return Console.run("psql -c '\\l'", :sync=>true).scan(/^ (\w+)/).map{|i| "- #{i}/"}
12
+ end
13
+
14
+ puts "
15
+ - .tables/
16
+ - .create_db :foo
17
+ - .drop_db :foo
18
+ "
19
+ end
20
+
21
+ def self.create_db name
22
+ Console.run "createdb #{name}"
23
+ end
24
+
25
+ def self.drop_db name
26
+ Console.run "dropdb #{name}"
27
+ end
28
+
29
+ def self.tables db
30
+ db.sub! /\/$/, ''
31
+ txt = Console.run "psql #{db} -c '\\d'", :sync=>true
32
+ end
33
+
34
+ end
@@ -0,0 +1,5 @@
1
+ class Pre
2
+ def self.menu
3
+ Browser.html "<pre>#{ENV['txt']}</pre>"
4
+ end
5
+ end
@@ -0,0 +1,39 @@
1
+ class Python
2
+ def self.menu
3
+ "
4
+ > Pass python code to run
5
+ | print('hey')
6
+ "
7
+ end
8
+
9
+ def self.menu_after txt, *args
10
+ # Do nothing if .menu created output
11
+ return nil if txt
12
+
13
+ txt = ENV['txt']
14
+ return nil if txt.nil?
15
+
16
+ txt = Python.run_internal txt
17
+ txt
18
+ end
19
+
20
+ def self.run_block
21
+ # Get block contents
22
+ txt, left, right = View.txt_per_prefix #:prefix=>Keys.prefix
23
+
24
+ result = self.run_internal txt
25
+ # Insert result at end of block
26
+ orig = Location.new
27
+ View.cursor = right
28
+ Line.to_left
29
+ View.insert result.gsub(/^/, ' ')
30
+ orig.go
31
+ end
32
+
33
+ def self.run_internal txt
34
+ # Write to temp file
35
+ File.open("/tmp/tmp.py", "w") { |f| f << txt }
36
+ # Call js
37
+ Console.run "python /tmp/tmp.py", :sync=>true
38
+ end
39
+ end
@@ -0,0 +1,160 @@
1
+ require "ruby_console"
2
+
3
+ class Rails
4
+
5
+ CODE_SAMPLES = %q<
6
+ # Show options to help create new rails app
7
+ - Show options: Rails.menu
8
+ >
9
+
10
+ def self.menu
11
+ "
12
+ - .start/
13
+ - .generate/
14
+ - app/
15
+ - model/
16
+ - resource/
17
+ - controller/
18
+ - scaffold/
19
+ - .interact/
20
+ - .rails console/
21
+ - .sqlite console/
22
+ - .models/
23
+ - .setup/
24
+ - .db/
25
+ - .migrate/
26
+ - .use rspec/
27
+ - .general/
28
+ - .rails version/
29
+ "
30
+ end
31
+
32
+ def self.menu_after txt, *args
33
+ txt
34
+ end
35
+
36
+ def self.menu_before *path
37
+
38
+ dir = Projects.current # Returns dir in tree, or current project (top of projects.menu)
39
+
40
+ # Don't intercede if already rails app or trying to generate
41
+ return nil if ["generate", "general"].member?(path[0]) || File.exists?("#{dir}app")
42
+
43
+ # If not a rails dir, give option to generate
44
+ return "
45
+ | No rails app in #{dir} yet. Generate it?
46
+ - generate/app/
47
+
48
+ | Not project-specific
49
+ - general/
50
+ "
51
+ end
52
+
53
+ def self.rails_version
54
+ "| #{`rails --version`}"
55
+ end
56
+
57
+ def self.use_rspec
58
+ dir = Projects.current
59
+
60
+ txt = "
61
+ @ #{dir}
62
+ - 1. Add these lines:
63
+ - Gemfile
64
+ |+group :development, :test do
65
+ |+ gem 'rspec-rails'
66
+ |+end
67
+ |
68
+ - 2. Run these commands:
69
+ % bundle
70
+ % rails g rspec:install
71
+ |
72
+ - 3. Delete the test/ dir:
73
+ % rm -r test/
74
+ "
75
+ end
76
+
77
+
78
+ def self.models
79
+ dir = Projects.current
80
+ dir = "#{dir}app/models/"
81
+
82
+ entries = Dir.new(dir).entries.select{|o| o =~ /^\w/}
83
+ entries.map{|o| "@r/#{TextUtil.camel_case o[/\w+/]}.first/"}.join("\n")
84
+ end
85
+
86
+ def self.sqlite_console
87
+ Console.run "sqlite3 db/development.sqlite3", :dir=>Projects.current, :buffer=>"sqlite console"
88
+ ".flash - opened console!"
89
+ end
90
+
91
+ def self.rails_console
92
+ Console.run "rails c", :dir=>Projects.current, :buffer=>"rails console"
93
+ ".flash - opened console!"
94
+ end
95
+
96
+ def self.generate what, name=nil, detail=nil
97
+
98
+ examples = "
99
+ > Example fields
100
+ | id:primary_key
101
+ | name:string
102
+ | description:text
103
+ | quantity:integer
104
+ | price:decimal
105
+ | purchased_at:datetime
106
+ | delivery:boolean
107
+ | user:references
108
+ ".unindent
109
+
110
+ case what
111
+ when "app"
112
+ Console.run "rails new . --skip-bundle", :dir=>Projects.current
113
+ return "- generating rails app..."
114
+ when "model", "resource", "scaffold"
115
+ return View.prompt "Enter a name" if ! name
116
+ return examples if ! detail
117
+ fields = ENV['txt'].gsub("\n", ' ').strip
118
+ Console.run "rails g #{what} #{name} #{fields}", :dir=>Projects.current
119
+ return "- generating #{what}..."
120
+ when "controller"
121
+ return View.prompt "Enter a name" if ! name
122
+ return View.prompt "Enter an action" if ! detail
123
+ Console.run "rails g controller #{name} #{detail}", :dir=>Projects.current
124
+ return "- generating controller..."
125
+ end
126
+
127
+ "- Don't know how to generate a '#{what}'!"
128
+ end
129
+
130
+ def self.start *args
131
+
132
+ # If 1st arg is number, assume it's the port
133
+ port = args[0] =~ /^\d+$/ ? args.shift : nil
134
+
135
+ # If 'browse', just bring up in browser
136
+ if args == ['browse']
137
+ Firefox.url "http://localhost:#{port || 3000}/"
138
+ return ".flash - opened in browser!"
139
+ end
140
+
141
+ command = "rails s"
142
+ command << " -p #{port}" if port
143
+
144
+ Console.run command, :dir=>Projects.current, :buffer=>"rails server"
145
+
146
+ # Check whether it's already running
147
+ "| Rails app was already running\n- browse/"
148
+ "| Starting rails app...\n- browse/"
149
+
150
+ end
151
+
152
+ def self.command txt
153
+ Console.run txt, :dir=>Projects.current
154
+ end
155
+
156
+ def self.migrate
157
+ self.command "rake db:migrate"
158
+ end
159
+
160
+ end
@@ -0,0 +1,12 @@
1
+ class Rake
2
+ def self.menu task=nil
3
+
4
+ if task.nil? # If no task passed, show all
5
+ txt = Console.run 'rake -T', :sync=>true
6
+ return "- Error: no rake file." if txt =~ /^No Rakefile found/
7
+ return txt.scan(/^rake ([\w:]+)/).join("\n")
8
+ end
9
+
10
+ Console.run "rake #{task}" # If task passed, run it
11
+ end
12
+ end
@@ -0,0 +1,168 @@
1
+ require 'net/http'
2
+ require 'uri'
3
+ require 'timeout'
4
+ require 'keys'
5
+
6
+ class Redmine
7
+
8
+ @@url ||= 'http://foo.com:80/wiki/1'
9
+ def self.url= to; @@url = to; end
10
+ def self.url; @@url; end
11
+
12
+ def self.menu
13
+ puts "
14
+ + .pages/
15
+ - .start
16
+ - local: http://localhost:3401/wiki/gateway
17
+ - remote: http://rlitio.chase.com:3401/wiki/1
18
+ "
19
+ end
20
+
21
+ def self.pages page=nil
22
+ if page # If page was passed, open it
23
+ self.open page
24
+ return
25
+ end
26
+
27
+ # Otherwise, print list
28
+ t = self.http_get "#{@@url}/Page_index/special" rescue return
29
+ t.scan(/<a href="\/wiki\/1\/([\w-]+)"/) { |m| puts "- #{m[0]}" }
30
+ ""
31
+ end
32
+
33
+ def self.redmine_to_xiki txt
34
+
35
+ # Angle brackets
36
+ txt.gsub!('&lt;', '<'); txt.gsub!('&gt;', '>')
37
+ txt.gsub!('&amp;', '&'); txt.gsub!('&quot;', '"')
38
+
39
+ (1..7).to_a.reverse.each do |i| # Headers
40
+ txt.gsub!(/^#{'#' * i}/, "#{'|' * i} ")
41
+ end
42
+ (1..9).to_a.reverse.each do |i| # Bullets
43
+ txt.gsub!(/^#{'\\*' * i}/, "#{' ' * (i-1)}-")
44
+ end
45
+
46
+ txt
47
+ end
48
+
49
+ def self.xiki_to_redmine txt
50
+ # Headers (h1. etc)
51
+ (1..7).to_a.reverse.each { |i| txt.gsub!(/^#{'\\|' * i} /, "#{'#' * i}") }
52
+ (1..9).to_a.reverse.each { |i| txt.gsub!(/^#{' ' * (i-1)}-/, "#{'*' * i}") }
53
+ txt
54
+ end
55
+
56
+ def self.open name
57
+
58
+ # TODO grab token into a buffer name
59
+ version = "no_version"
60
+ wiki, version = self.page_from_server name
61
+ self.redmine_to_xiki wiki
62
+ View.to_after_bar
63
+ View.to_buffer("redmine/#{name}/#{version}")
64
+
65
+ # Set mode and use relevant key shortcuts
66
+ Notes.mode; $el.use_local_map $el.elvar.redmine_mode_map
67
+ self.apply_styles
68
+
69
+ if View.empty? # If nothing there yet, insert
70
+ $el.insert wiki
71
+ end
72
+ Move.top
73
+ ""
74
+ end
75
+
76
+ def self.page_from_server name
77
+
78
+ t = self.http_get "#{@@url}/#{name}/edit" rescue
79
+ return
80
+ version = t[/<input id="content_version".+value="(\d+)"/, 1]
81
+ wiki = t[/<textarea.*?>(.+)<\/textarea>/m, 1]
82
+ wiki.gsub!("\C-m", '')
83
+ [wiki, version]
84
+ end
85
+
86
+ def self.save
87
+ name, version = View.buffer_name.split('/')[1..2]
88
+ txt = View.txt # Get text from buffer
89
+ return puts("- Not a redmine page!") unless txt
90
+ self.xiki_to_redmine txt
91
+
92
+ # Get text from server
93
+ server_txt, server_version = self.page_from_server name
94
+
95
+ # If version is same, save
96
+ if version == server_version
97
+ res = Net::HTTP.post_form(URI.parse("#{@@url}/#{name}/edit"), { # Save
98
+ 'content[version]' => version, 'content[text]' => txt
99
+ })
100
+ message "- page saved"
101
+ $el.rename_buffer "redmine/#{name}/#{version.to_i + 1}" # Rename
102
+ else # Otherwise show diff
103
+ message "- wrong version, show diffs!"
104
+ View.to_buffer "*redmine_collision: #{name}/#{server_version}"
105
+ notes_mode; $el.use_local_map $el.elvar.redmine_mode_map
106
+
107
+ View.clear
108
+ $el.insert "- collision with #{name}/#{server_version}!\n\n"
109
+ $el.insert self.diff(server_txt, txt)
110
+ end
111
+ end
112
+
113
+ def self.http_get url
114
+ t = nil
115
+ begin
116
+ timeout(2) do
117
+ t = Net::HTTP.get URI.parse(url)
118
+ end
119
+ rescue Exception => e
120
+ puts "- Couldn't connect to url (#{url}): #{e.message}!"
121
+ raise e
122
+ end
123
+ t
124
+ end
125
+
126
+ def self.init
127
+ unless $el.boundp :redmine_mode_map
128
+ # Create new map
129
+ $el.elvar.redmine_mode_map = $el.make_sparse_keymap
130
+ # Inherit notes_mode_map!
131
+ $el.set_keymap_parent $el.elvar.redmine_mode_map, $el.elvar.notes_mode_map
132
+ end
133
+ Keys.XS(:redmine_mode_map) { Redmine.save }
134
+
135
+ # Make C-. follow link
136
+ Launcher.add(/\[\[.+\]\]/) do |line| # Redmine wiki links
137
+ name = line[/\[\[(.+?)\]\]/, 1]
138
+ name.gsub!(/ /, "_")
139
+ Redmine.open(name)
140
+ end
141
+ end
142
+
143
+ def self.diff a, b
144
+ temp_path_a = "/tmp/diff_tmp_a.txt"
145
+ temp_path_b = "/tmp/diff_tmp_b.txt"
146
+ File.open(temp_path_a, "w") { |f| f << a }
147
+ File.open(temp_path_b, "w") { |f| f << b }
148
+ diff = $el.shell_command_to_string "diff -w -U 0 \"#{temp_path_a}\" \"#{temp_path_b}\""
149
+ DiffLog.format("server/", "diff/", diff)
150
+ end
151
+
152
+ def self.apply_styles
153
+ # Strikethrough
154
+ Styles.define(:strike, :strike => true)
155
+ Styles.apply("^ *- \\(-.+-\\)$", nil, :strike)
156
+ # _italic_
157
+ Styles.define(:redmine_green, :bold => true, :fg => "33dd33")
158
+ Styles.apply(" _[a-zA-Z0-9 ]+_ ", :redmine_green)
159
+ Styles.apply(" _[a-zA-Z0-9 ]+_$", :redmine_green)
160
+
161
+ end
162
+
163
+ def self.start
164
+ Rails.start '$o/redmine/trunk', @@url[/\d+/]
165
+ end
166
+
167
+ end
168
+ # Redmine.init
@@ -0,0 +1,204 @@
1
+ gem 'httparty'; require 'httparty'
2
+ gem 'json'; require 'json'
3
+ gem 'riak-client'; require 'riak'
4
+
5
+ module Riak
6
+
7
+ RIAK_URL = "http://127.0.0.1:8098"
8
+
9
+ def self.menu
10
+ [ ".buckets/",
11
+ ".index/",
12
+ ".filter/",
13
+ ".get 'foo/bar'",
14
+ ".help/",
15
+ ".log/",
16
+ ".ping/",
17
+ ]
18
+ end
19
+
20
+ def self.buckets bucket=nil, key=nil, txt=nil
21
+
22
+
23
+ if key
24
+ key.sub! /\/$/, ''
25
+ key.gsub! '/', '%2F'
26
+ key.sub! /^"(.*)"$/, "\\1"
27
+ end
28
+
29
+ bucket.sub! /\/$/, '' if bucket
30
+
31
+ if txt
32
+ # If 0, delete
33
+ if Keys.prefix == 0
34
+ self.delete "#{bucket}/#{key}"
35
+ return "- deleted!"
36
+ end
37
+
38
+ # Save text if txt passed
39
+ txt = Tree.siblings :string=>true
40
+
41
+ data = YAML::load(txt)
42
+
43
+ self.put "#{bucket}/#{key}", YAML::load(txt)
44
+
45
+ return "- saved!"
46
+ end
47
+
48
+ # Show contents of object if passed
49
+ if key
50
+ Files.append "~/.emacs.d/riak_log.notes", "- Riak.buckets \"#{bucket}\", \"#{key}\"/"
51
+
52
+ key = "#{bucket}/#{key}"
53
+
54
+ begin
55
+ return self.get_hash(key).to_yaml.sub(/^--- \n/, '').gsub(/^/, '| ')
56
+ rescue Exception=>e
57
+ return self.get_hash(key, :raw=>true).gsub(/^/, '| ')
58
+ end
59
+ end
60
+ # Show contents of bucket if passed
61
+ return self.get_hash("#{bucket}?keys=true")['keys'].sort.map{|o| "#{o}/"} if bucket
62
+ # Nothing passed, so list buckets
63
+ self.get_hash("?buckets=true")["buckets"].sort.map{|o| "#{o}/"}
64
+ end
65
+
66
+ def self.filter bucket=nil, *args
67
+ bucket.sub! /\/$/, '' if bucket
68
+
69
+ if args.any?
70
+ args = args.join(', ').sub(/\/$/, '')
71
+
72
+ Files.append "~/.emacs.d/riak_log.notes", "- Riak.filter \"#{bucket}\", #{args}/"
73
+
74
+ args = eval "[#{args}]"
75
+
76
+ results = Riak::MapReduce.new(Riak::Client.new).
77
+ add(bucket, args).
78
+ map("function(v){ return [v.key]; }", :keep => true).
79
+ run
80
+
81
+ return results.sort.reverse.to_yaml.sub(/\A--- \n/, '').gsub(/^/, '| ')
82
+ end
83
+
84
+ if bucket # Examples
85
+ return ["['matches', 'b']/", "['starts_with', 'a']/", "['between', 'a', 'b']/", "['or', [['eq', 'a']], [['less_than', 'g']]]/", "['tokenize', '-', 1], ['eq', 'basho']/"]
86
+ end
87
+
88
+ self.buckets # Delegate to .buckets to list buckets
89
+
90
+ end
91
+
92
+ def self.index bucket=nil, search=nil
93
+
94
+ if search
95
+ results = self.get_hash "#{bucket}/index/#{search}", :root=>'buckets'#, :raw=>'true'
96
+ return results.to_yaml.gsub(/^/, '| ')
97
+ end
98
+
99
+ if bucket # Examples
100
+ return ["zip_bin/eq/43215/", "zip_bin/range/40000/49999/"]
101
+ end
102
+
103
+ self.buckets # Delegate to .buckets to list buckets
104
+ end
105
+
106
+ def self.get path, txt=nil
107
+
108
+ if txt
109
+ txt = Tree.siblings :string=>true
110
+ self.put path, YAML::load(txt)
111
+ return "- saved!"
112
+ end
113
+
114
+ hash = self.get_hash(path).to_yaml.sub("--- \n", '').gsub(/^/, '| ')
115
+
116
+ end
117
+
118
+ def self.get_hash path, options={}
119
+ begin
120
+ response = HTTParty.get("#{RIAK_URL}/#{options[:root]||'riak'}/#{path}")
121
+ rescue Exception=>e
122
+ raise "Riak not running?"
123
+ end
124
+
125
+ return response.code if response.code.to_s !~ /^2/
126
+ if options[:raw]
127
+ response.body
128
+ else
129
+ result = ::JSON[response.body]
130
+ result['_link'] = response.headers['link'].split(', ') if Keys.prefix_u
131
+ result
132
+ end
133
+ end
134
+
135
+ def self.post path, options={}
136
+ # If no body passed in, wrap necessary stuff around it
137
+ if options[:body].nil?
138
+ options = {
139
+ :body=>options.to_json,
140
+ :headers=>{'Content-Type'=>'application/json'},
141
+ }
142
+ end
143
+
144
+ HTTParty.post("#{RIAK_URL}/riak/#{path}", options)
145
+ end
146
+
147
+ def self.put path, options={}
148
+ # If no body passed in, wrap necessary stuff around it
149
+ if options[:body].nil?
150
+ options = {
151
+ :body=>options.to_json,
152
+ :headers=>{'Content-Type'=>'application/json'},
153
+ }
154
+ end
155
+
156
+ HTTParty.put("#{RIAK_URL}/riak/#{path}", options)
157
+ nil
158
+ end
159
+
160
+ def self.delete path
161
+ HTTParty.delete "#{RIAK_URL}/riak/#{path}"
162
+ end
163
+
164
+ def self.help bucket=nil, key=nil
165
+ "
166
+ | To save
167
+ | - C-enter on object body
168
+ |
169
+ | To delete
170
+ | - C-0, C-enter on object body
171
+ ".unindent
172
+ end
173
+
174
+ def self.ping
175
+ `#{Bookmarks['$riak']}/bin/riak ping`
176
+ end
177
+
178
+ def self.log
179
+ txt = File.read File.expand_path("~/.emacs.d/riak_log.notes")
180
+ txt = txt.split("\n").reverse.uniq.join("\n")
181
+ end
182
+
183
+ end
184
+
185
+ Keys.enter_list_riak do
186
+ Launcher.insert '- Riak.menu/'
187
+ end
188
+
189
+ Keys.enter_list_buckets do
190
+ Launcher.insert '- buckets/'
191
+ end
192
+
193
+ Launcher.add("riak") do |path|
194
+ "
195
+ - @buckets/
196
+ "
197
+ end
198
+
199
+ Launcher.add "buckets" do |path|
200
+ args = path.split('/')[1..-1]
201
+ Riak.buckets(*args)
202
+ end
203
+
204
+ CodeTree.add_menu "Riak" # Force it, since we're a module