Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'master' into rcov

Conflicts:
	.gitignore
	Rakefile
  • Loading branch information...
commit 318b6609da68225ab2d9963d8ef819d4a58039f2 2 parents 2444007 + 6349327
@ujihisa ujihisa authored
Showing with 7,197 additions and 2,744 deletions.
  1. +3 −0  .gitignore
  2. +139 −0 ChangeLog
  3. +0 −4 History.txt
  4. +0 −68 Manifest.txt
  5. +0 −1  PostInstall.txt
  6. +66 −30 README.rdoc
  7. +74 −44 Rakefile
  8. +1 −2  bin/termtter
  9. +37 −0 doc/Termtter-1.0-Release-Note-English.txt
  10. +37 −0 doc/Termtter-1.0-Release-Note.txt
  11. +0 −9 lib/filter/en2ja.rb
  12. +0 −8 lib/filter/english.rb
  13. +0 −22 lib/filter/expand-tinyurl.rb
  14. +0 −17 lib/filter/ignore.rb
  15. +0 −20 lib/filter/yhara.rb
  16. +0 −26 lib/plugin/bomb.rb
  17. +0 −24 lib/plugin/confirm.rb
  18. +0 −12 lib/plugin/cool.rb
  19. +0 −57 lib/plugin/english.rb
  20. +0 −17 lib/plugin/erb.rb
  21. +0 −73 lib/plugin/favorite.rb
  22. +0 −6 lib/plugin/fib.rb
  23. +0 −64 lib/plugin/filter.rb
  24. +0 −40 lib/plugin/follow.rb
  25. +0 −58 lib/plugin/group.rb
  26. +0 −60 lib/plugin/growl.rb
  27. +0 −57 lib/plugin/hatebu.rb
  28. +0 −61 lib/plugin/history.rb
  29. +0 −16 lib/plugin/keyword.rb
  30. +0 −55 lib/plugin/log.rb
  31. +0 −24 lib/plugin/msagent.rb
  32. +0 −34 lib/plugin/multi_reply.rb
  33. +0 −15 lib/plugin/notify-send.rb
  34. +0 −17 lib/plugin/otsune.rb
  35. +0 −33 lib/plugin/outputz.rb
  36. +0 −1  lib/plugin/pause.rb
  37. +0 −48 lib/plugin/plugin.rb
  38. +0 −36 lib/plugin/quicklook.rb
  39. +0 −38 lib/plugin/reblog.rb
  40. +0 −3  lib/plugin/reload.rb
  41. +0 −43 lib/plugin/scrape.rb
  42. +0 −22 lib/plugin/screen.rb
  43. +0 −4 lib/plugin/shell.rb
  44. +0 −31 lib/plugin/sl.rb
  45. +0 −7 lib/plugin/spam.rb
  46. +0 −238 lib/plugin/standard_plugins.rb
  47. +0 −60 lib/plugin/stdout.rb
  48. +0 −41 lib/plugin/system_status.rb
  49. +0 −53 lib/plugin/update_editor.rb
  50. +0 −67 lib/plugin/uri-open.rb
  51. +0 −21 lib/plugin/wassr_post.rb
  52. +0 −18 lib/plugin/yonda.rb
  53. +27 −0 lib/plugins/addspace.rb
  54. +15 −0 lib/plugins/april_fool.rb
  55. +39 −0 lib/plugins/bomb.rb
  56. +14 −0 lib/plugins/clear.rb
  57. +47 −0 lib/plugins/command_plus.rb
  58. +40 −0 lib/plugins/confirm.rb
  59. +7 −0 lib/plugins/cool.rb
  60. +23 −0 lib/plugins/countter.rb
  61. +43 −0 lib/plugins/curry.rb
  62. +97 −0 lib/plugins/db.rb
  63. +15 −0 lib/plugins/defaults.rb
  64. +69 −0 lib/plugins/defaults/alias.rb
  65. +22 −0 lib/plugins/defaults/auto_reload.rb
  66. +120 −0 lib/plugins/defaults/command_line.rb
  67. +12 −0 lib/plugins/defaults/exec.rb
  68. +7 −0 lib/plugins/defaults/fib.rb
  69. +39 −0 lib/plugins/defaults/retweet.rb
  70. +504 −0 lib/plugins/defaults/standard_commands.rb
  71. +72 −0 lib/plugins/defaults/standard_completion.rb
  72. +155 −0 lib/plugins/defaults/stdout.rb
  73. +18 −0 lib/plugins/devel.rb
  74. +17 −0 lib/plugins/en2ja.rb
  75. +25 −0 lib/plugins/english.rb
  76. +13 −0 lib/plugins/erb.rb
  77. +14 −0 lib/plugins/exec_and_update.rb
  78. +56 −0 lib/plugins/expand-tinyurl.rb
  79. +3 −2 lib/{filter/fib.rb → plugins/fib_filter.rb}
  80. +12 −0 lib/plugins/fibyou.rb
  81. +69 −0 lib/plugins/filter.rb
  82. +192 −0 lib/plugins/github-issues.rb
  83. +3 −2 lib/{plugin → plugins}/graduatter.rb
  84. +27 −0 lib/plugins/grass.rb
  85. +89 −0 lib/plugins/group.rb
  86. +61 −0 lib/plugins/growl.rb
  87. +143 −0 lib/plugins/growl2.rb
  88. +59 −0 lib/plugins/hatebu.rb
  89. +58 −0 lib/plugins/hatebu_and_update.rb
  90. +13 −0 lib/plugins/hi.rb
  91. +93 −0 lib/plugins/history.rb
  92. +82 −0 lib/plugins/http_server.rb
  93. BIN  lib/plugins/http_server/favicon.ico
  94. +117 −0 lib/plugins/http_server/index.html
  95. +38 −0 lib/plugins/hugeurl.rb
  96. +25 −0 lib/plugins/ignore.rb
  97. +6 −0 lib/plugins/irb.rb
  98. +131 −0 lib/plugins/irc_gw.rb
  99. +33 −0 lib/plugins/itunes.rb
  100. +18 −0 lib/plugins/keyword.rb
  101. +25 −0 lib/plugins/l2.rb
  102. +29 −0 lib/plugins/list_with_opts.rb
  103. +70 −0 lib/plugins/log.rb
  104. +11 −0 lib/plugins/mark.rb
  105. +10 −0 lib/plugins/me.rb
  106. +5 −0 lib/plugins/modify_arg_hook_sample.rb
  107. +38 −0 lib/plugins/msagent.rb
  108. +34 −0 lib/plugins/multi_output.rb
  109. +32 −0 lib/plugins/multi_post.rb
  110. +22 −0 lib/plugins/multi_reply.rb
  111. +22 −0 lib/plugins/notify-send.rb
  112. +52 −0 lib/plugins/notify-send2.rb
  113. +58 −0 lib/plugins/notify-send3.rb
  114. +44 −0 lib/plugins/open.rb
  115. +47 −0 lib/plugins/open_url.rb
  116. +15 −0 lib/plugins/otsune.rb
  117. +33 −0 lib/plugins/outputz.rb
  118. +3 −0  lib/plugins/pause.rb
  119. +30 −0 lib/plugins/pool.rb
  120. +9 −0 lib/plugins/post_exec_hook_sample.rb
  121. +9 −0 lib/plugins/pre_exec_hook_sample.rb
  122. +11 −2 lib/{plugin → plugins}/primes.rb
  123. +9 −0 lib/plugins/protected_filter.rb
  124. +9 −0 lib/plugins/quick_exit.rb
  125. +41 −0 lib/plugins/quicklook.rb
  126. +23 −0 lib/plugins/random.rb
  127. +40 −0 lib/plugins/reblog.rb
  128. +3 −0  lib/plugins/reload.rb
  129. 0  lib/{filter → plugins}/reply.rb
  130. +3 −1 lib/{filter → plugins}/reverse.rb
  131. +10 −6 lib/{plugin → plugins}/say.rb
  132. +81 −0 lib/plugins/saykanji.rb
  133. +41 −0 lib/plugins/scrape.rb
  134. +20 −0 lib/plugins/screen-notify.rb
  135. +24 −0 lib/plugins/screen.rb
  136. +12 −0 lib/plugins/search_url.rb
  137. +9 −0 lib/plugins/shell.rb
  138. +48 −0 lib/plugins/sl.rb
  139. +16 −0 lib/plugins/spam.rb
  140. +55 −0 lib/plugins/storage.rb
  141. +37 −0 lib/plugins/storage/DB.rb
  142. +83 −0 lib/plugins/storage/status.rb
  143. +30 −0 lib/plugins/storage/status_mook.rb
  144. +22 −0 lib/plugins/switch_user.rb
  145. +33 −0 lib/plugins/system_status.rb
  146. +18 −0 lib/plugins/timer.rb
  147. +45 −0 lib/plugins/tinyurl.rb
  148. +24 −0 lib/plugins/train.rb
  149. +17 −5 lib/{plugin → plugins}/translation.rb
  150. +84 −0 lib/plugins/trends.rb
  151. +46 −0 lib/plugins/twitpic.rb
  152. +94 −0 lib/plugins/typable_id.rb
  153. +53 −0 lib/plugins/update_editor.rb
  154. +71 −0 lib/plugins/uri-open.rb
  155. +94 −0 lib/plugins/wassr.rb
  156. +22 −0 lib/plugins/wassr_post.rb
  157. +45 −0 lib/plugins/whois.rb
  158. +12 −25 lib/{plugin → plugins}/yhara.rb
  159. +8 −0 lib/plugins/yhara_filter.rb
  160. +21 −0 lib/plugins/yonda.rb
  161. +17 −127 lib/termtter.rb
  162. +39 −0 lib/termtter/active_rubytter.rb
  163. +46 −1 lib/termtter/api.rb
  164. +281 −214 lib/termtter/client.rb
  165. +62 −34 lib/termtter/command.rb
  166. +70 −0 lib/termtter/config.rb
  167. +30 −0 lib/termtter/config_setup.rb
  168. +15 −0 lib/termtter/config_template.erb
  169. +12 −8 lib/termtter/connection.rb
  170. +31 −0 lib/termtter/hook.rb
  171. +51 −0 lib/termtter/optparse.rb
  172. +0 −24 lib/termtter/status.rb
  173. +159 −0 lib/termtter/system_extensions.rb
  174. +17 −0 lib/termtter/task.rb
  175. +112 −0 lib/termtter/task_manager.rb
  176. +0 −146 lib/termtter/twitter.rb
  177. +0 −11 lib/termtter/user.rb
  178. +4 −0 lib/termtter/version.rb
  179. +7 −2 run_termtter.rb
  180. +0 −10 spec/plugin/cool_spec.rb
  181. +0 −14 spec/plugin/fib_spec.rb
  182. +0 −18 spec/plugin/filter_spec.rb
  183. +0 −24 spec/plugin/plugin_spec.rb
  184. +0 −9 spec/plugin/shell_spec.rb
  185. +0 −14 spec/plugin/spam_spec.rb
  186. +0 −21 spec/plugin/standard_plugins_spec.rb
  187. +10 −0 spec/plugins/cool_spec.rb
  188. +13 −0 spec/plugins/curry_spec.rb
  189. +62 −0 spec/plugins/db_spec.rb
  190. +19 −0 spec/plugins/english_spec.rb
  191. +15 −0 spec/plugins/fib_spec.rb
  192. +18 −0 spec/plugins/filter_spec.rb
  193. +8 −0 spec/plugins/pause_spec.rb
  194. +15 −0 spec/plugins/primes_spec.rb
  195. +10 −0 spec/plugins/shell_spec.rb
  196. +8 −0 spec/plugins/sl_spec.rb
  197. +4 −0 spec/plugins/spam_spec.rb
  198. +23 −0 spec/plugins/standard_commands_spec.rb
  199. +12 −0 spec/plugins/storage/DB_spec.rb
  200. +24 −0 spec/plugins/storage/status_spec.rb
  201. +20 −0 spec/plugins/whois_spec.rb
  202. +7 −0 spec/spec_helper.rb
  203. +70 −0 spec/termtter/active_rubytter_spec.rb
  204. +394 −15 spec/termtter/client_spec.rb
  205. +99 −106 spec/termtter/command_spec.rb
  206. +121 −0 spec/termtter/config_spec.rb
  207. +78 −0 spec/termtter/hook_spec.rb
  208. +16 −0 spec/termtter/optparse_spec.rb
  209. +78 −0 spec/termtter/task_manager_spec.rb
  210. +22 −0 spec/termtter/task_spec.rb
  211. +0 −27 spec/termtter/user_spec.rb
  212. +22 −34 spec/termtter_spec.rb
  213. +0 −24 tasks/manifest.rake
  214. +25 −29 termtter.gemspec
  215. +0 −84 test/test_termtter.rb
View
3  .gitignore
@@ -1,2 +1,5 @@
*.swp
coverage
+*~
+*.gem
+pkg
View
139 ChangeLog
@@ -0,0 +1,139 @@
+== 1.3.1 2009-08-10
+
+Takaaki SONE:
+ Fixed help message for Exit
+ added protected column to users table.
+
+Tomohiro Nishimura:
+ add new command around the alias
+ more powerful list command available!
+ add alias method to Client module
+
+emasaka:
+ Added protected sign to default timeline_format.
+ Added hugeurl plugin: alternative of expand-tinyurl
+
+jugyo:
+ Fixed for termtter shutdown when raise network error.
+ Added a method 'command_exists?'
+ Changed to apply TermColor.unescape for status.text
+ Changed retweet command to add confirmation for protected user.
+
+ujihisa:
+ Ignore case for completion of user's screen name
+
+== 1.3.0 2009-07-27
+
+Koichiro Ohba (3):
+ Added group_filter.
+
+Shin-ichiro OGAWA (1):
+ Fix retweet command.
+
+Tomohiro Nishimura (17):
+ add github-issues plugin
+ add icomment command to github-issues plugin
+ add isearch command to github-issues plugin
+ now help command allow you to search specific one
+ add functionality of hash tag tracking for sl plugin
+ fix Termtter::Client.plug bug
+ add pool plugin
+ add comment for retweet plugin
+ register_command can take command name as symbol
+ add trends plugin
+ remove configatron method (already 1.2.0)
+
+Yasuhiro Matsumoto (1):
+ some color was broken on windows.
+
+emasaka (33):
+ expand-tinyurl.rb: added force_encoding for Ruby 1.9
+ expand-tinyurl.rb: added config "skip_users"
+ expand-tinyurl.rb: added config "shortters"
+ expand-tinyurl.rb: add_filter -> register_hook
+ expand-tinyurl.rb: refactored expand_url method
+ set permission 0600 when creating config file
+ modified regexp of ff.im (plugin/expand-tinyurl.rb)
+ moved "t.plug 'auto_reload'" to the end of default config file.
+ Defined dummy Encoding::UTF_8 for Ruby 1.8 (expand-tinyurl.rb)
+ use multiple URL shortening APIs.
+ separated options and texts in nofity-send* plugins
+ trap SIGCONT to redraw prompt
+
+jugyo (79):
+ Fixed modify_arg_for_* hook
+ Added a hook point for completion.
+ Changed the signature of register_hook
+ Updated a sample script
+ Added a plugin 'standard_completion'.
+ Changed to load a plugin 'standard_completion' as default plugin.
+ Changed to use completion of standard_completion.rb
+ Implemented easy_reply
+ Implemented completion for hashtags.
+ Fixed regex for completion of search keywords.
+ Implemented a db plugins.
+ Fixed bug for associations.
+ Added a method 'confirm'.
+ Added a command 'db_clear'.
+ Changed confirm to call block if given.
+ Fixed confirm to call pause and resume.
+ Added commands 'do_list' and 'db_execute'
+ Removed alias 'l' from command 'db_list'.
+ Fixed hook :collect_statuses_for_db
+ Fixed a bug devel option is not working.
+ Removed setting for config.devel
+ Changed to remove dir 'rdoc' when 'rake clean'.
+ Fixed 'spec_opts'
+ Create a plugin 'defaults' that load deafult plugins.
+ Added a task to generate gemspec.
+ Fixed completion_proc
+ Fixed path of standard plugins.
+ Implemented the http sever plugin.
+ Changed port configurable
+ Changed path for execute command.
+ Changed to handle files
+ Added favicon.ico
+ Created a web client.
+ Fixed bugs for ajax
+ Modified html
+ コマンドの処理を全て TaskManager の invoke_and_wait の中でやるようにした
+ Fixed commands plug and plugins.
+ Added a option 'show_as_thread' to stdout.
+ Added options sticky and priority to plugin growl.
+ Applied a patch from Kiwamu Okabe to notify-send3
+ Added a command 'twitpic' for upload an image to TwitPic.
+ Moved a plug 'devel'.
+ Added a default task to Rakefile
+ Moved retweet plugin to defaults
+ Moved fib plugin to defaults
+ Moved exec plugin to defaults
+ Added a alias '!' for exec command.
+ Renamed alias of exit command 'e' to 'quit'.
+ Deleted a disused plugin
+ Created a plugin 'command_line'.
+ Added a irb command.
+ Changed to case sensitive for user name completion.
+ Fixed Rakefile. (closed #82)
+ Changed to not handle error at TaskManager#invoke_and_wait
+ Created the hook point 'prepare_command', and clean the code.
+ Changed to use the hook point 'prepare_command' for curry.
+ Added completion for curry command.
+ Created a new hook point named 'prepare_prompt'.
+ Changed to use prepare_prompt for curry, and changed specs as command.
+
+ktgy (5):
+ Added saykanji.rb
+
+ujihisa (13):
+ Added -m
+ Fixed wrong warning message
+ Termtter::Client.plug: Enable to receive array
+ Added new plugin 'curry'
+
+yoppi (2):
+ Added 'whois' command
+
+== 0.0.1 2008-12-26
+
+* 1 major enhancement:
+ * Initial release
View
4 History.txt
@@ -1,4 +0,0 @@
-== 0.0.1 2008-12-26
-
-* 1 major enhancement:
- * Initial release
View
68 Manifest.txt
@@ -1,68 +0,0 @@
-History.txt
-Manifest.txt
-PostInstall.txt
-README.rdoc
-Rakefile
-bin/termtter
-lib/filter/en2ja.rb
-lib/filter/english.rb
-lib/filter/expand-tinyurl.rb
-lib/filter/fib.rb
-lib/filter/ignore.rb
-lib/filter/reply.rb
-lib/filter/reverse.rb
-lib/filter/yhara.rb
-lib/plugin/bomb.rb
-lib/plugin/confirm.rb
-lib/plugin/cool.rb
-lib/plugin/english.rb
-lib/plugin/erb.rb
-lib/plugin/favorite.rb
-lib/plugin/fib.rb
-lib/plugin/filter.rb
-lib/plugin/follow.rb
-lib/plugin/graduatter.rb
-lib/plugin/group.rb
-lib/plugin/growl.rb
-lib/plugin/hatebu.rb
-lib/plugin/history.rb
-lib/plugin/keyword.rb
-lib/plugin/log.rb
-lib/plugin/msagent.rb
-lib/plugin/multi_reply.rb
-lib/plugin/notify-send.rb
-lib/plugin/otsune.rb
-lib/plugin/outputz.rb
-lib/plugin/pause.rb
-lib/plugin/plugin.rb
-lib/plugin/primes.rb
-lib/plugin/quicklook.rb
-lib/plugin/reblog.rb
-lib/plugin/reload.rb
-lib/plugin/say.rb
-lib/plugin/scrape.rb
-lib/plugin/screen.rb
-lib/plugin/shell.rb
-lib/plugin/sl.rb
-lib/plugin/spam.rb
-lib/plugin/standard_plugins.rb
-lib/plugin/stdout.rb
-lib/plugin/system_status.rb
-lib/plugin/translation.rb
-lib/plugin/update_editor.rb
-lib/plugin/uri-open.rb
-lib/plugin/wassr_post.rb
-lib/plugin/yhara.rb
-lib/plugin/yonda.rb
-lib/termtter.rb
-lib/termtter/api.rb
-lib/termtter/client.rb
-lib/termtter/command.rb
-lib/termtter/connection.rb
-lib/termtter/status.rb
-lib/termtter/twitter.rb
-lib/termtter/user.rb
-run_termtter.rb
-test/friends_timeline.json
-test/search.json
-test/test_termtter.rb
View
1  PostInstall.txt
@@ -1 +0,0 @@
-
View
96 README.rdoc
@@ -1,66 +1,102 @@
= termtter
-http://github.com/jugyo/termtter
+http://termtter.org/
== DESCRIPTION:
-Termtter is a terminal based Twitter client
+Termtter is a terminal based Twitter client.
== FEATURES/PROBLEMS:
== SYNOPSIS:
-Run:
+=== Run:
- termtter
+ % termtter
-== REQUIREMENTS:
+=== Some Termtter Commands:
-* json
-* configatron
+Show help
-== INSTALL:
+ > help
+
+Update status
+
+ > update hi!
+
+Show replies
- sudo gem source -a http://gems.github.com (you only have to do this once)
- sudo gem install jugyo-termtter
+ > replies
+
+Search
+
+ > search termtter
+
+== REQUIREMENTS:
- if you want to install gem package from source code, install like following.
+* json_pure or json
+* termcolor
+* rubytter
+* highline
- git clone git://github.com/jugyo/termtter.git
- cd termtter
- rake manifest
- rake gemspec
- gem build termtter.gemspec
- gem install *.gem
+== INSTALL:
-Just run a new command termtter.
+ % sudo gem install termtter
- termtter
+== CONFIGURATION:
-Termtter generates a configuration file named '.termtter' in your HOME directory.
+Termtter generates a configuration file named '~/.termtter/config'.
You can edit the file anytime.
- vim ~/.termtter
+ % vim ~/.termtter/config
- configatron.user_name = 'USERNAME'
- configatron.password = 'PASSWORD'
+ config.user_name = 'USERNAME'
+ config.password = 'PASSWORD'
If you would like to use proxy server, add configurations like this:
- configatron.proxy.host = 'PROXYHOST'
- configatron.proxy.port = 'PROXYPORT'
- configatron.proxy.user_name = 'USERNAME'
- configatron.proxy.password = 'PASSWORD'
+ config.proxy.host = 'PROXYHOST'
+ config.proxy.port = 'PROXYPORT'
+ config.proxy.user_name = 'USERNAME'
+ config.proxy.password = 'PASSWORD'
+
+You can to load plugins in this way:
+
+ Termtter::Client.init do |t|
+ t.plug 'fib'
+ t.plug 'growl'
+ end
To update the config, just restart your termtter proccess.
== FORUM:
-http://www.lingr.com/room/termtter
+http://groups.google.co.jp/group/termtter
+
+== TODO:
+
+- Enhance the document and spec
+- Improve the UI(a status view, etc...)
+
+== ADVANCED USAGE:
+
+ t.plug 'curry'
+
+Your termtter can curry commands.
+
+ > curry u
+ u > hi
+ updated => hi
+ u > curry @ujm
+ u @ujm > hi
+ updated => @ujm hi
+ u @ujm > uncurry
+ >
-== DOCUMENT:
+You can also type `<` as curry.
-http://wiki.github.com/jugyo/termtter/home (in Japanese)
+ > < u
+ u >
== LICENSE:
View
118 Rakefile
@@ -1,44 +1,74 @@
-%w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
-require File.dirname(__FILE__) + '/lib/termtter'
-
-# Generate all the Rake tasks
-# Run 'rake -T' to see list of generated tasks (from gem root directory)
-$hoe = Hoe.new('termtter', Termtter::VERSION) do |p|
- p.author = %w[jugyo hakobe motemen koichiro Sixeight mattn ujihisa yanbe hitode909 bubblegum].sort_by{|i|i.downcase}
- p.email = ['jugyo.org@gmail.com']
- p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
- p.post_install_message = 'PostInstall.txt' # TODO remove if post-install message not required
- p.rubyforge_name = p.name # TODO this is default value
- p.extra_deps = [
- ['json'],
- ['configatron'],
- ['highline'],
- ]
- #p.extra_dev_deps = [
- # ['newgem', ">= #{::Newgem::VERSION}"]
- #]
-
- p.clean_globs |= %w[**/.DS_Store tmp *.log]
- path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
- p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
- p.rsync_args = '-av --delete --ignore-errors'
-end
-
-require 'newgem/tasks' # load /tasks/*.rake
-Dir['tasks/**/*.rake'].each { |t| load t }
-
-# TODO - want other tests/tasks run by default? Add them to the list
-# task :default => [:spec, :features]
-
-require 'spec/rake/spectask'
-desc 'run all specs'
-Spec::Rake::SpecTask.new do |t|
- t.spec_files = FileList['spec/**/*_spec.rb']
- t.spec_opts = ['-c']
-end
-
-desc "update coverage files and open"
-task :rcov do
- sh "rcov -Ispec:lib:lib spec/*_spec.rb"
- sh "open coverage/index.html" if PLATFORM['darwin']
-end
+$:.unshift File.dirname(__FILE__) + '/lib'
+
+require 'spec/rake/spectask'
+require 'rake/clean'
+require 'rake/gempackagetask'
+require 'rake/rdoctask'
+require 'termtter/version'
+
+desc "default task"
+task :default => [:install, :spec]
+
+name = 'termtter'
+version = Termtter::VERSION
+
+spec = Gem::Specification.new do |s|
+ s.name = name
+ s.version = version
+ s.summary = "Terminal based Twitter client."
+ s.description = "Termtter is a terminal based Twitter client."
+ s.files = %w(Rakefile README.rdoc ChangeLog) + Dir.glob("{lib,spec,test}/**/*")
+ s.executables = ["kill_termtter", "termtter"]
+ s.add_dependency("json_pure", ">= 1.1.3")
+ s.add_dependency("highline", ">= 1.5.0")
+ s.add_dependency("termcolor", ">= 0.3.1")
+ s.add_dependency("rubytter", ">= 0.6.4")
+ s.authors = %w(jugyo ujihisa)
+ s.email = 'jugyo.org@gmail.com'
+ s.homepage = 'http://termtter.org/'
+ s.rubyforge_project = 'termtter'
+ s.has_rdoc = true
+ s.rdoc_options = ["--main", "README.rdoc", "--exclude", "spec"]
+ s.extra_rdoc_files = ["README.rdoc", "ChangeLog"]
+end
+
+Rake::GemPackageTask.new(spec) do |p|
+ p.need_tar = true
+end
+
+task :gemspec do
+ filename = "#{name}.gemspec"
+ open(filename, 'w') do |f|
+ f.write spec.to_ruby
+ end
+ puts <<-EOS
+ Successfully generated gemspec
+ Name: #{name}
+ Version: #{version}
+ File: #{filename}
+ EOS
+end
+
+task :install => [ :package ] do
+ sh %{sudo gem install pkg/#{name}-#{version}.gem}
+end
+
+task :uninstall => [ :clean ] do
+ sh %{sudo gem uninstall #{name}}
+end
+
+desc 'run all specs'
+Spec::Rake::SpecTask.new do |t|
+ t.spec_files = FileList['spec/**/*_spec.rb']
+ t.spec_opts = ['-c']
+end
+
+Rake::RDocTask.new do |t|
+ t.rdoc_dir = 'rdoc'
+ t.title = "rest-client, fetch RESTful resources effortlessly"
+ t.options << '--line-numbers' << '--inline-source' << '-A cattr_accessor=object'
+ t.options << '--charset' << 'utf-8'
+ t.rdoc_files.include('README.rdoc', 'lib/**/*.rb')
+end
+
+CLEAN.include [ 'pkg', 'rdoc' ]
View
3  bin/termtter
@@ -1,6 +1,5 @@
#!/usr/bin/env ruby
-
-$KCODE = 'u'
+# -*- coding: utf-8 -*-
require 'rubygems'
require 'termtter'
View
37 doc/Termtter-1.0-Release-Note-English.txt
@@ -0,0 +1,37 @@
+Termtter 1.0 Released
+Today March 15, 2009, we have released Termtter 1.0 as a stable version. Termtter is a twitter client software working on terminal emulators, which is very easy to extend functions. Termtter is the only one twitter client which can calculates fibonacci numbers congenitally.
+
+== INSTALLATION
+ sudo gem install termtter
+
+== HOW TO USE
+Termtter will ask you what are your twitter account(email) and password are when you boot termtter for the first time. Termtter will make a config file ~/.termtter/config and will boot. Now you can post messages to twitter by typing "u Hello, world!" and return key on the termtter.
+
+Let's fix your ~/.termtter/config and try various plugins! You can post the 100th fibonacci number to twitter by (1) uncomment the line "plugin 'fib'" and reboot termtter and (2) type "fib 100" on the termtter.
+http://twitter.com/ujm/status/1330652098
+
+== Changes after Termtter 0.8 series
+Big changes:
+* Termtter config file: from ~/.termtter to ~/.termtter/config
+* Enable to use user-plugin located in ~/.termtter/plugins
+* Storing timelins on sqlite3 db
+* Enable to specify your config file by option -f
+
+Small changes:
+* Not to use gem package configatron
+* Enable to target what event will be filtered only in English (plugin/english)
+
+See all chages:
+http://jugyo.lighthouseapp.com/projects/22944-termtter/tickets?q=state%3Aclosed
+
+== Termtter Camp (termtterspa2009, Ruby Spa)
+We worked to relase our new Termtter 1.0 in Termtter Camp 2009. That's a hackathon which 8 hackers meet near the lake biwako (a.k.a. the Japanese Great Lake). We enjoyed nice and natural spa and hacking.
+
+Participants: hitode909, jugyo, ujihisa, Sixeight, koichiroo, nay, udonchan, repeatedly
+
+== Links
+Termtter trunk
+http://github.com/jugyo/termcolor/tree/master
+
+Old Release Note
+http://jugyo.org/blog/2931
View
37 doc/Termtter-1.0-Release-Note.txt
@@ -0,0 +1,37 @@
+Termtter 1.0 をリリースしました
+本日2009年3月15日、Termtter の最新安定版であるバージョン1.0をリリースしました。Termtterはターミナルエミュレータ上で動作する Twitter クライアントで、拡張性に極端に優れているという特徴があります。フィボナッチ数列を計算する機能が標準で提供されている、世界で唯一のtwitterクライアントです。
+
+== インストール
+ sudo gem install termtter
+
+== 使い方
+termtterを起動すると、初回はあなたのtwitterアカウントとパスワードが聞かれます。それによって設定ファイル~/.termtter/configが生成され、同時にtermtterが起動します。"u Hello, world!"などと書いてエンターキーを叩くことによって、termtterからtwitterに発言することができます。
+
+~/.termtter/configを修正し、さまざまなプラグインを試してみましょう。たとえばplugin 'fib'の行のコメントを外してtermtterを再起動することによって、"fib 100"と入力することで100番目のフィボナッチ数列の値をtwitterにポストすることができます。
+http://twitter.com/ujm/status/1330652098
+
+== 0.8系からの変更点
+大きな変更点:
+* 設定ファイルが~/.termtterから~/.termtter/configを指すようになりました。なお、古い設定ファイル~/.termtterがある状態でtermtterを起動すると、自動的に最新版の構成になるようmkdir, mvなどが行われます。
+* termtter本体に標準添付されているプラグイン以外にも、自作プラグインを~/.termtter/plugins以下に配置することで、自作プラグインを容易に使用することができます。
+* TimelineをSQLite3のデータベースに保存することにより、termtterを常時起動してもそれほど負荷がかからないようになりました。
+* 起動時のオプションで設定ファイルを切り替えることができるようになりました。
+
+細かい変更点:
+* gemのパッケージconfigatronを使わないようになりました。
+* Englishプラグインでtimelineでは英語だけだがrepliesでは日本語も通すなどのオプションを設定できるようになりました。
+
+その他の変更点はこちらをご覧ください。
+http://jugyo.lighthouseapp.com/projects/22944-termtter/tickets?q=state%3Aclosed
+
+== Termtter合宿 (termtterspa2009, Ruby温泉)
+Termtter 1.0 のリリース作業はTermtter合宿で行われました。これはTermtterのコミッタのうち8名が滋賀県の琵琶湖のほとりで宿にこもってひたすらTermtterの1.0への課題を克服し、温泉に浸かるような行為を行いました。
+
+参加者: hitode909, jugyo, ujihisa, Sixeight, koichiroo, nay, udonchan, repeatedly
+
+== 参考リンク
+開発中のTermtter
+http://github.com/jugyo/termcolor/tree/master
+
+2009年1月時点の Termtter リリースノート (当時のバージョンは不明)
+http://jugyo.org/blog/2931
View
9 lib/filter/en2ja.rb
@@ -1,9 +0,0 @@
-plugin 'translation'
-
-Termtter::Client.add_filter do |statuses|
- statuses.each do |s|
- if s.english?
- s.text = translate(s.text, 'en|ja')
- end
- end
-end
View
8 lib/filter/english.rb
@@ -1,8 +0,0 @@
-# -*- coding: utf-8 -*-
-
-Termtter::Client.add_filter do |statuses|
- statuses.select{|s| s.english? }
-end
-
-# filter-english.rb
-# select English post only
View
22 lib/filter/expand-tinyurl.rb
@@ -1,22 +0,0 @@
-module Termtter::Client
- add_filter do |statuses|
- statuses.each do |s|
- s.text.gsub!(%r'(http://tinyurl\.com(/[\w/]+))') do |m|
- expand_tinyurl($2) || $1
- end
- end
- statuses
- end
-end
-
-def expand_tinyurl(path)
- http_class = Net::HTTP
- unless configatron.proxy.host.empty?
- http_class = Net::HTTP::Proxy(configatron.proxy.host,
- configatron.proxy.port,
- configatron.proxy.user_name,
- configatron.proxy.password)
- end
- res = http_class.new('tinyurl.com').head(path)
- res['Location']
-end
View
17 lib/filter/ignore.rb
@@ -1,17 +0,0 @@
-
-configatron.filters.ignore.set_default(:words, [])
-
-module Termtter::Client
- add_filter do |statuses|
- ignore_words = configatron.filters.ignore.words
- statuses.delete_if do |s|
- ignore_words.any? {|i| i =~ s.text }
- end
- end
-end
-
-# filter/ignore.rb
-# ignore words
-# setting
-# configatron.filters.ignore.words = [ /ignore/, /words/ ]
-
View
20 lib/filter/yhara.rb
@@ -1,20 +0,0 @@
-# -*- coding: utf-8 -*-
-
-module Termtter
-
- class Status
- def yharian?
- self.text =~ /^(?:\s|(y\s)|(?:hara\s))+\s*(?:y|(?:hara))(?:\?|!|\.)?\s*$/
- end
- end
-
- module Client
- add_filter do |statuses|
- statuses.select{|s| s.yharian? }
- end
- end
-end
-
-# filter-yhara.rb
-# select Yharian post only
-
View
26 lib/plugin/bomb.rb
@@ -1,26 +0,0 @@
-module Termtter
- class Status
- def bomb?
- /爆発|bomb/ =~ self.text
- end
- end
-
- module Client
- add_help 'bomb WORD', 'Bomb it'
- add_command %r'^bomb\s+(.+)$' do |m, t|
- bomb = m[1]
- msg = "#{bomb} 爆発しろ!"
-
- puts msg
- t.update_status msg
- end
- end
-end
-
-# bomb.rb
-# Bomb it!
-#
-# See http://gyazo.com/4b33517380673d92f51a52e675ecdb02.png .
-# configatron.plugins.stdout.timeline_format =
-# '<%= color(time, 90) %> <%= s.bomb? ? color(color(status, 41), 37) : color(status, status_color) %> <%= color(id, 90) %>'
-# vim: fenc=utf8
View
24 lib/plugin/confirm.rb
@@ -1,24 +0,0 @@
-module Termtter::Client
-
- add_command /^confirm\s+(.*)/ do |m, t|
- text = m[1]
- unless text.empty?
- pause
- print "update? #{text} [Y/n] "
- buf = Readline.readline("", false)
- t.update_status(text) if /^y?$/i =~ buf
- resume
- end
- end
-
- add_completion do |input|
- case input
- when /^(confirm)\s+(.*)@([^\s]*)$/
- find_user_candidates $3, "#{$1} #{$2}@%s"
- else
- ['confirm'].grep(/^#{Regexp.quote input}/)
- end
- end
-
-end
-
View
12 lib/plugin/cool.rb
@@ -1,12 +0,0 @@
-module Termtter::Client
- add_help 'cool {SCREENNAME}', 'update "@{SCREENNAME} cool."'
- add_macro /^cool ([^\s]*)/, "update @%s cool."
- add_completion do |input|
- case input
- when /^c$/
- ['cool']
- when /^cool ([^\s]*)/
- find_user_candidates $1, "cool %s"
- end
- end
-end
View
57 lib/plugin/english.rb
@@ -1,57 +0,0 @@
-require 'erb'
-
-module Termtter
- Client.clear_hooks # FIXME: not to clear all but to clear just stdout.rb
-
- configatron.set_default(
- :timeline_format,
- '<%= color(time, 90) %> <%= color(status, status_color) %> <%= color(id, 90) %>')
-
- def color(str, num)
- "\e[#{num}m#{str}\e[0m"
- end
-
- # FIXME: The code below is a copy from stdout.rb so it's not DRY. DRY it.
-
- Client.add_hook do |statuses, event|
- colors = %w(0 31 32 33 34 35 36 91 92 93 94 95 96)
-
- case event
- when :update_friends_timeline, :list_friends_timeline, :list_user_timeline, :show, :replies
- unless statuses.empty?
- statuses.reverse! if event == :update_friends_timeline
- statuses.each do |s|
- text = s.text.gsub("\n", '')
- next unless Status.english?(text) # if you substitute "if" for "unless", this script will be "japanese.rb"
- status_color = colors[s.user_screen_name.hash % colors.size]
- status = "#{s.user_screen_name}: #{text}"
- if s.in_reply_to_status_id
- status += " (reply to #{s.in_reply_to_status_id})"
- end
-
- time_format = case event
- when :update_friends_timeline, :list_friends_timeline
- '%H:%M:%S'
- else
- '%m-%d %H:%M'
- end
- time = "(#{s.created_at.strftime(time_format)})"
-
- id = s.id
-
- puts ERB.new(configatron.timeline_format).result(binding)
- end
- end
- when :search
- statuses.each do |s|
- text = s.text.gsub("\n", '')
- status_color = colors[s.user_screen_name.hash % colors.size]
-
- status = "#{s.user_screen_name}: #{text}"
- time = "(#{s.created_at.strftime('%m-%d %H:%M')})"
- id = s.id
- puts ERB.new(configatron.timeline_format).result(binding)
- end
- end
- end
-end
View
17 lib/plugin/erb.rb
@@ -1,17 +0,0 @@
-require 'erb'
-
-module Termtter::Client
- add_command /^(update|u)\s+(.*)/ do |m, t|
- text = ERB.new(m[2]).result(binding).gsub(/\n/, ' ')
- unless text.empty?
- t.update_status(text)
- puts "=> #{text}"
- end
- end
-end
-
-# erb.rb
-# enable to <%= %> in the command update
-# example:
-# > u erb test <%= 1+1 %>
-# => erb test 2
View
73 lib/plugin/favorite.rb
@@ -1,73 +0,0 @@
-module Termtter::Client
- add_help 'favorite,fav ID', 'Favorite a status'
-
- add_command %r'^(?:favorite|fav)\s+(\d+)\s*$' do |m, t|
- id = m[1]
- res = t.favorite(id)
- if res.code == '200'
- puts "Favorited status ##{id}"
- else
- puts "Failed: #{res}"
- end
- end
-
- add_help 'favorite,fav USER', 'Favorite last status on the user'
-
- add_command %r'^(?:favorite|fav)\s+@(.+)\s*$' do |m, t|
- user = m[1].strip
- statuses = t.get_user_timeline(user)
- unless statuses.empty?
- id = statuses[0].id
- text = statuses[0].text
- res = t.favorite(id)
- if res.code == '200'
- puts %Q(Favorited last status ##{id} on user @#{user}: "#{text}")
- else
- puts "Failed: #{res}"
- end
- end
- end
-
- if public_storage[:log]
- add_help 'favorite,fav /WORD', 'Favorite a status by searching'
-
- add_command %r'^(?:favorite|fav)\s+/(.+)$' do |m, t|
- pat = Regexp.new(m[1])
- statuses = public_storage[:log].select {|s| pat =~ s.text }
- if statuses.size == 1
- status = statuses.first
- res = t.favorite(status.id)
- if res.code == '200'
- puts %Q(Favorited "#{status.user_screen_name}: #{status.text}")
- else
- puts "Failed: #{res}"
- end
- else
- puts "#{pat} does not match single status"
- end
- end
- end
-
- add_completion do |input|
- case input
- when /^(favorite|fav)\s+@(.*)/
- find_user_candidates $2, "#{$1} @%s"
- when /^(favorite|fav)\s+(\d*)/
- find_status_id_candidates $2, "#{$1} %s"
- else
- %w(favorite).grep(/^#{Regexp.quote input}/)
- end
- end
-end
-
-module Termtter
- class Twitter
- def favorite(id)
- uri = "#{@connection.protocol}://twitter.com/favourings/create/#{id}.json"
-
- @connection.start('twitter.com', @connection.port) do |http|
- http.request(post_request(uri))
- end
- end
- end
-end
View
6 lib/plugin/fib.rb
@@ -1,6 +0,0 @@
-def fib(n)i=0;j=1;n.times{j=i+i=j};i end
-module Termtter::Client
-add_command /^fib\s+(\d+)/ do|m,t|t.update_status x="fib(#{n=m[1].to_i}) = #{fib n}"
-puts"=> #{x}"end
-add_command /^fibyou\s(\w+)\s(\d+)/ do|m,t|puts"=> #{t.update_status("@#{m[1]} fib(#{n=m[2].to_i}) = #{fib n}")}"end end
-# TODO: use add_macro
View
64 lib/plugin/filter.rb
@@ -1,64 +0,0 @@
-
-module Termtter::Client
-
- public_storage[:filters] = []
-
- add_help 'filter FILE', 'Apply a filter'
- add_command /^filter\s+(.*)/ do |m, t|
- begin
- result = filter m[1].strip
- rescue LoadError
- result = false
- ensure
- puts "=> #{result.inspect}"
- end
- end
-
- add_help 'unfilter', 'Clear all filters'
- add_command /^unfilter\s*$/ do |m, t|
- clear_filters
- public_storage[:filters].clear
- puts '=> filter cleared'
- end
-
- add_help 'filters', 'Show list of applied filters'
- add_command /^filters\s*$/ do |m, t|
- unless public_storage[:filters].empty?
- puts public_storage[:filters].join(', ')
- else
- puts 'no filter was applied'
- end
- end
-
- def self.find_filter_candidates(a, b, filters)
- if a.empty?
- filters.to_a
- else
- filters.grep(/^#{Regexp.quote a}/i)
- end.
- map {|u| b % u }
- end
-
- filters = Dir["#{File.dirname(__FILE__)}/../filter/*.rb"].map do |f|
- f.match(%r|([^/]+).rb$|)[1]
- end
- add_completion do |input|
- if input =~ /^(filter)\s+(.*)/
- find_filter_candidates $2, "#{$1} %s", filters
- else
- %w[ filter filters unfilter ].grep(/^#{Regexp.quote input}/)
- end
- end
-end
-
-# filter.rb
-# a dynamic filter loader
-# example
-# > list
-# (15:49:00) termtter: こんにちは
-# (15:48:02) termtter: hello
-# > filter english
-# => true
-# > list
-# (15:48:02) termtter: hello
-# vim: fenc=utf8
View
40 lib/plugin/follow.rb
@@ -1,40 +0,0 @@
-module Termtter::Client
- add_help 'follow USER', 'Follow user'
- add_help 'leave USER', 'Leave user'
-
- add_command %r'^(follow|leave)\s+(\w+)\s*$' do |m, t|
- user = m[2]
- res = t.social(user, m[1].to_sym)
- if res.code == '200'
- puts "#{m[1].capitalize}ed user @#{user}"
- else
- puts "Failed: #{res}"
- end
- end
-
- add_completion do |input|
- case input
- when /^(follow|leave)?\s+(.*)/
- find_user_candidates $2, "#{$1} %s"
- else
- %w[follow leave].grep(/^#{Regexp.quote input}/)
- end
- end
-end
-
-module Termtter
- class Twitter
- def social(user, type)
- type =
- case type.to_sym
- when :follow then 'create'
- when :leave then 'destroy'
- end
- uri = "#{@connection.protocol}://twitter.com/friendships/#{type}/#{user}.json"
-
- @connection.start('twitter.com', @connection.port) do |http|
- http.request(post_request(uri))
- end
- end
- end
-end
View
58 lib/plugin/group.rb
@@ -1,58 +0,0 @@
-configatron.set_default('plugins.group.groups', {})
-
-module Termtter
- class Status
- def is_member?(group = nil)
- if group
- configatron.plugins.group.groups[:group].include? self.user_screen_name
- else
- configatron.plugins.group.groups.values.flatten.include? self.user_screen_name
- end
- end
- end
-end
-
-module Termtter::Client
- if public_storage[:log]
- add_help 'group,g GROUPNAME', 'Filter by group members'
-
- add_command /^(?:group|g)\s*$/ do |m, t|
- configatron.plugins.group.groups.each_pair do |key, value|
- puts "#{key}: #{value.join(',')}"
- end
- end
-
- add_command /^(?:group|g)\s+(.+)/ do |m, t|
- group_name = m[1].to_sym
- group = configatron.plugins.group.groups[group_name]
- statuses = group ? public_storage[:log].select { |s|
- group.include?(s.user_screen_name)
- } : []
- call_hooks(statuses, :search, t)
- end
-
- def self.find_group_candidates(a, b)
- configatron.plugins.group.groups.keys.map {|k| k.to_s}.
- grep(/^#{Regexp.quote a}/).
- map {|u| b % u }
- end
-
- add_completion do |input|
- case input
- when /^(group|g)\s+(.+)/
- find_group_candidates($2, "#{$1} %s")
- when /^(group|g)\s+$/
- configatron.plugins.group.groups.keys
- else
- %w(group).grep(/^#{Regexp.quote input}/)
- end
- end
- end
-end
-
-# group.rb
-# plugin 'group'
-# configatron.plugins.group.groups = {
-# :rits => %w(hakobe isano hitode909)
-# }
-# NOTE: group.rb needs plugin/log
View
60 lib/plugin/growl.rb
@@ -1,60 +0,0 @@
-require 'tmpdir'
-require 'open-uri'
-require 'uri'
-require 'fileutils'
-
-begin
- require 'ruby-growl'
- growl = Growl.new "localhost", "termtter", "termtter status notification"
-rescue LoadError
- growl = nil
-end
-
-configatron.plugins.growl.set_default(:icon_cache_dir, "#{Dir.tmpdir}/termtter-icon-cache-dir")
-FileUtils.mkdir_p(configatron.plugins.growl.icon_cache_dir) unless File.exist?(configatron.plugins.growl.icon_cache_dir)
-
-def get_icon_path(s)
- cache_file = "%s/%s%s" % [ configatron.plugins.growl.icon_cache_dir,
- s.user_screen_name,
- File.extname(s.user_profile_image_url) ]
- if File.exist?(cache_file) && (File.atime(cache_file) + 24*60*60) > Time.now
- return cache_file
- else
- Thread.new do
- File.open(cache_file, "wb") do |f|
- f << open(URI.escape(s.user_profile_image_url)).read
- end
- end
- return nil
- end
-end
-
-queue = []
-Thread.new do
- loop do
- begin
- if s = queue.pop
- unless growl
- arg = ['growlnotify', s.user_screen_name, '-m', s.text.gsub("\n",''), '-n', 'termtter']
- #icon_path = get_icon_path(s)
- #arg += ['--image', icon_path] if icon_path
- system *arg
- else
- growl.notify "termtter status notification", s.text, s.user_screen_name
- end
- end
- rescue => e
- puts e
- puts e.backtrace.join("\n")
- end
- sleep 0.1
- end
-end
-
-Termtter::Client.add_hook do |statuses, event|
- if !statuses.empty? && event == :update_friends_timeline
- statuses.reverse.each do |s|
- queue << s
- end
- end
-end
View
57 lib/plugin/hatebu.rb
@@ -1,57 +0,0 @@
-require 'rubygems'
-require 'atomutil'
-
-module Termtter::Client
- add_help 'hatebu ID', 'Hatena bookmark a status'
-
- add_command %r'^hatebu\s+(\d+)(.*)$' do |m, t|
- id = m[1]
- comment = m[2].strip
- statuses = public_storage[:log].select { |s| s.id == id }
- unless statuses.empty?
- status = statuses.first
- else
- status = t.show(id).first
- end
- auth = auth = Atompub::Auth::Wsse.new({
- :username => configatron.plugins.hatebu.username,
- :password => configatron.plugins.hatebu.password,
- })
- link = Atom::Link.new({
- :href => "http://twitter.com/#{status.user_screen_name}/status/#{status.id}",
- :rel => 'related',
- :type => 'text/html',
- })
- entry = Atom::Entry.new({
- :link => link,
- :title => 'dummy',
- :summary => comment,
- })
- req = Net::HTTP::Post.new 'http://b.hatena.ne.jp/atom/post'
- req['User-Agent'] = 'Mozilla/5.0'
- req['Content-Type'] = 'application/atom+xml'
- req['Slug'] = 'termtter'
- req.body = entry.to_s
- auth.authorize(req)
- Net::HTTP.start('b.hatena.ne.jp', 80) do |http|
- res = http.request(req)
- end
- end
-
- add_completion do |input|
- case input
- when /^(hatebu)\s+(\d*)$/
- find_status_id_candidates $2, "#{$1} %s"
- else
- %w(hatebu).grep(/^#{Regexp.quote input}/)
- end
- end
-end
-
-# hatebu.rb
-# hatena bookmark it!
-#
-# configatron.plugins.hatebu.username = 'your-username-on-hatena'
-# configatron.plugins.hatebu.password = 'your-password-on-hatena'
-#
-# hatebu 1114860346 [termtter][‚±‚ê‚Í‚·‚²‚¢]mattn++
View
61 lib/plugin/history.rb
@@ -1,61 +0,0 @@
-require 'zlib'
-
-configatron.plugins.history.
- set_default(:filename, '~/.termtter_history')
-configatron.plugins.history.
- set_default(:keys, [:log, :users, :status_ids])
-configatron.plugins.history.
- set_default(:max_of_history, 100)
-
-module Termtter::Client
- def self.load_history
- filename = File.expand_path(configatron.plugins.history.filename)
- keys = configatron.plugins.history.keys
-
- if File.exist?(filename)
- begin
- history = Marshal.load Zlib::Inflate.inflate(File.read(filename))
- rescue Zlib::DataError
- history = Marshal.load File.read(filename)
- end
- if history
- keys.each do |key|
- public_storage[key] = history[key] if history[key]
- end
- Readline::HISTORY.push *history[:history] if history[:history]
- puts "history loaded(#{File.size(filename)}bytes)"
- end
- end
- end
-
- def self.save_history
- filename = File.expand_path(configatron.plugins.history.filename)
- keys = configatron.plugins.history.keys
- history = { }
- keys.each do |key|
- history[key] = public_storage[key]
- end
- max_of_history = configatron.plugins.history.max_of_history
- history[:history] = Readline::HISTORY.to_a.reverse.uniq.reverse
- if history[:history].size > max_of_history
- history[:history] = history[:history][-max_of_history..-1]
- end
-
- File.open(filename, 'w') do |f|
- f.write Zlib::Deflate.deflate(Marshal.dump(history))
- end
- puts "history saved(#{File.size(filename)}bytes)"
- end
-
- add_hook do |statuses, event|
- case event
- when :initialize
- load_history
- when :exit
- save_history
- end
- end
-end
-
-# history.rb
-# save log to file
View
16 lib/plugin/keyword.rb
@@ -1,16 +0,0 @@
-configatron.set_default('plugins.keyword.keywords', [])
-
-module Termtter
- class Status
- def has_keyword?
- configatron.plugins.keyword.keywords.find { |k| k === self.text }
- end
- alias :has_keyword :has_keyword?
- end
-end
-
-# keyword.rb
-# provides a keyword watching method
-# example config
-# configatron.plugins.stdout.timeline_format = '<%= color(time, 90) %> <%= color(status, s.has_keyword ? 4 : status_color) %> <%= color(id, 90) %>'
-# configatron.plugins.keyword.keywords = [ /motemen/ ]
View
55 lib/plugin/log.rb
@@ -1,55 +0,0 @@
-module Termtter::Client
- public_storage[:log] = []
- configatron.plugins.log.set_default('max_size', 1/0.0)
- configatron.plugins.log.set_default('print_max_size', 30)
-
- add_help '/WORD', 'Search log for WORD'
- add_help 'log', 'Show local log'
- add_help 'log (USER(S)) (MAX)', 'Show local log of the user(s)'
-
- add_hook do |statuses, event|
- case event
- when :pre_filter
- public_storage[:log] += statuses
- max_size = configatron.plugins.log.max_size
- if public_storage[:log].size > max_size
- public_storage[:log] = public_storage[:log][-max_size..-1]
- end
- public_storage[:log] = public_storage[:log].uniq.sort_by{|a| a.created_at} if statuses.first
- end
- end
-
- add_command %r'^/(.+)' do |m, t|
- pat = Regexp.new(m[1])
- statuses = public_storage[:log].select { |s| s.text =~ pat }
- call_hooks(statuses, :search, t)
- end
-
- # log
- add_command /^(log)\s*$/ do |m, t|
- statuses = public_storage[:log]
- print_max = configatron.plugins.log.print_max_size
- print_max = 0 if statuses.size < print_max
- call_hooks(statuses[-print_max..-1], :search, t)
- end
-
- # log (user) (max)
- add_command /^(log)\s+(.+)\s*/ do |m, t|
- vars = m[2].split(' ')
- print_max = vars.last =~ /^\d+$/ ? vars.pop.to_i : configatron.plugins.log.print_max_size
- id = vars
- statuses = id.first ? public_storage[:log].select{ |s| id.include? s.user_screen_name} : public_storage[:log]
- print_max = 0 if statuses.size < print_max
- call_hooks(statuses[-print_max..-1], :search, t)
- end
-
- add_completion do |input|
- case input
- when /^(log)\s+(.*)/
- find_user_candidates $2, "#{$1} %s"
- else
- %w[ log ].grep(/^#{Regexp.quote input}/)
- end
- end
-
-end
View
24 lib/plugin/msagent.rb
@@ -1,24 +0,0 @@
-raise 'msagent.rb runs only in windows' if RUBY_PLATFORM.downcase !~ /mswin(?!ce)|mingw|bccwin/
-require 'win32ole'
-require 'kconv'
-
-agent = WIN32OLE.new('Agent.Control.2')
-agent.connected = true
-agent.characters.load("Merlin", ENV['WINDIR'] + "\\msagent\\chars\\Merlin.acs")
-achar = agent.characters.character("Merlin")
-achar.languageID = 0x411
-achar.show
-
-Termtter::Client.add_hook do |statuses, event, t|
- if event == :exit
- achar.hide
- GC.start
- elsif !statuses.empty? && event == :update_friends_timeline
- statuses.reverse.each do |s|
- req = achar.speak("#{s.user_screen_name}: #{s.text}".tosjis)
- sleep 3
- WIN32OLE_EVENT.message_loop
- achar.stop(req)
- end
- end
-end
View
34 lib/plugin/multi_reply.rb
@@ -1,34 +0,0 @@
-module Termtter::Client
- add_help 'multi_reply, mp TEXT', 'reply to multi user'
- add_command /^(multi_reply|mr)\s+(.*)/ do |m, t|
- text = ERB.new(m[2]).result(binding).gsub(/\n/, ' ')
- unless text.empty?
- #targets, _, msg = text.match /(@(.+))*\s+(.+)/
- #targets.split(/\s+/).
- # map {|u| "#{u} #{msg}" }.
- # each do |post|
- # t.update_status(post)
- # puts "=> #{post}"
- # end
- /(@(.+))*\s+(.+)/ =~ text
- if $1
- msg = $3
- text = $1.split(/\s+/).map {|u| "#{u} #{msg}" }
- end
- Array(text).each do |post|
- t.update_status(post)
- puts "=> #{post}"
- end
- #
- end
- end
-
- add_completion do |input|
- case input
- when /^(multi_reply|mr)\s+(.*)@([^\s]*)$/
- find_user_candidates $3, "#{$1} #{$2}@%s"
- else
- %w[ mreply mp ].grep(/^#{Regexp.quote input}/)
- end
- end
-end
View
15 lib/plugin/notify-send.rb
@@ -1,15 +0,0 @@
-Termtter::Client.add_hook do |statuses, event|
- if !statuses.empty? && event == :update_friends_timeline
- max = 10
-
- text = statuses.take(max).map {|s|
- status_text = CGI.escapeHTML(s.text)
- status_text.gsub!(%r{https?://[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+},'<a href="\0">\0</a>')
- "<b>#{s.user_screen_name}:</b> <span font=\"9.0\">#{status_text}</span>"
- }.join("\n")
-
- text << %Q|\n<a href="http://twitter.com/">more...</a>| if statuses.size > max
-
- system 'notify-send', 'Termtter', text, '-t', '60000'
- end
-end
View
17 lib/plugin/otsune.rb
@@ -1,17 +0,0 @@
-module Termtter::Client
- add_help 'otsune {SCREENNAME}', 'update "@{SCREENNAME} 頭蓋骨の中身がお気の毒です"'
- add_help 'otsnue {SCREENNAME}', 'update "@{SCREENNAME} 頭が気の毒です"'
-
- add_macro /^otsune ([^\s]*)/, "update @%s 頭蓋骨の中身がお気の毒です."
- add_macro /^otsnue ([^\s]*)/, "update @%s 頭が気の毒です."
-
- add_completion do |input|
- case input
- when /^(otsune|otsnue) ([^\s]*)/
- find_user_candidates $2, "#{$1} %s"
- else
- %w[otsune otsnue].grep(/^#{Regexp.quote input}/)
- end
- end
-end
-# vim: fenc=utf8
View
33 lib/plugin/outputz.rb
@@ -1,33 +0,0 @@
-
-module Termtter::Client
- configatron.plugins.outputz.set_default(:uri, 'termtter://twitter.com/status/update')
-
- key = configatron.plugins.outputz.secret_key
- if key.instance_of? Configatron::Store
- puts 'Need your secret key'
- puts 'please set configatron.plugins.outputz.secret_key'
- else
- add_command /^(update|u)\s+(.*)/ do |m, t|
- text = ERB.new(m[2]).result(binding).gsub(/\n/, ' ')
- unless text.empty?
- t.update_status(text)
- puts "=> #{text}"
- end
- t.instance_variable_get('@connection').
- start('outputz.com', 80) do |http|
- key = CGI.escape key
- uri = CGI.escape configatron.plugins.outputz.uri
- size = text.split(//).size
- http.post('/api/post', "key=#{key}&uri=#{uri}&size=#{size}")
- end
- end
- end
-end
-
-# outputz.rb
-# a plugin that report to outputz your post
-#
-# settings (note: must this order)
-# configatron.plugins.outputz.secret_key = 'your secret key'
-# plugin 'outputz'
-
View
1  lib/plugin/pause.rb
@@ -1 +0,0 @@
-Termtter::Client.pause
View
48 lib/plugin/plugin.rb
@@ -1,48 +0,0 @@
-module Termtter::Client
-
- public_storage[:plugins] = Dir["#{File.dirname(__FILE__)}/*.rb"].map do |f|
- f.match(%r|([^/]+).rb$|)[1]
- end
-
- add_help 'plugin FILE', 'Load a plugin'
- add_command /^plugin\s+(.*)/ do |m, t|
- begin
- result = plugin m[1].strip
- rescue LoadError
- ensure
- puts "=> #{result.inspect}"
- end
- end
-
- add_help 'plugins', 'Show list of plugins'
- add_command /^plugins$/ do |m, t|
- puts public_storage[:plugins].sort.join("\n")
- end
-
- def self.find_plugin_candidates(a, b)
- public_storage[:plugins].
- grep(/^#{Regexp.quote a}/i).
- map {|u| b % u }
- end
-
- add_completion do |input|
- case input
- when /^(plugin)\s+(.+)/
- find_plugin_candidates $2, "#{$1} %s"
- when /^(plugin)\s+$/
- public_storage[:plugins].sort
- else
- %w[ plugin plugins ].grep(/^#{Regexp.quote input}/)
- end
- end
-end
-
-# plugin.rb
-# a dynamic plugin loader
-# example
-# > u <%= not erbed %>
-# => <%= not erbed %>
-# > plugin erb
-# => true
-# > u <%= 1 + 2 %>
-# => 3
View
36 lib/plugin/quicklook.rb
@@ -1,36 +0,0 @@
-require 'uri'
-require 'open-uri'
-require 'pathname'
-require 'tmpdir'
-
-configatron.plugins.quicklook.set_default(:quicklook_tmpdir, "#{Dir.tmpdir}/termtter-quicklook-tmpdir")
-tmpdir = Pathname.new(configatron.plugins.quicklook.quicklook_tmpdir)
-tmpdir.mkdir unless tmpdir.exist?
-
-def quicklook(url)
- tmpdir = Pathname.new(configatron.plugins.quicklook.quicklook_tmpdir)
- path = tmpdir + Pathname.new(url).basename
-
- Thread.new do
- open(path, 'w') do |f|
- f.write(open(url).read)
- end
- system("qlmanage -p #{path} > /dev/null 2>&1")
- end
-end
-
-module Termtter::Client
- add_command %r'^(?:quicklook|ql)\s+(\w+)$' do |m,t|
- id = m[1]
- status = t.show(id).first
-
- if (status)
- uris = URI.regexp.match(status.text).to_a
- quicklook(uris.first) unless uris.empty?
- end
- end
-end
-
-# quicklook.rb
-# TODO:
-# Close quicklook window automatically.
View
38 lib/plugin/reblog.rb
@@ -1,38 +0,0 @@
-require 'rubygems'
-require 'tumblr'
-
-module Termtter::Client
- add_help 'reblog ID', 'Tumblr Reblog a status'
-
- add_command %r'^reblog\s+(\d+)(.*)$' do |m, t|
- id = m[1]
- comment = m[2].strip
- statuses = public_storage[:log].select { |s| s.id == id }
- unless statuses.empty?
- status = statuses.first
- else
- status = t.show(id).first
- end
-
- Tumblr::API.write(configatron.plugins.reblog.email, configatron.plugins.reblog.password) do
- quote("#{status.text}", "<a href=\"http://twitter.com/#{status.user_screen_name}/status/#{status.id}\">Twitter / #{status.user_name}</a>")
- end
- end
-
- add_completion do |input|
- case input
- when /^(reblog)\s+(\d*)$/
- find_status_id_candidates $2, "#{$1} %s"
- else
- %w(reblog).grep(/^#{Regexp.quote input}/)
- end
- end
-end
-
-# reblog.rb
-# tumblr reblog it!
-#
-# configatron.plugins.reblog.email = 'your-email-on-tumblr'
-# configatron.plugins.reblog.password = 'your-password-on-tumblr'
-#
-# reblog 1114860346
View
3  lib/plugin/reload.rb
@@ -1,3 +0,0 @@
-module Termtter::Client
- add_macro /^reload$/, 'eval exec $0'
-end
View
43 lib/plugin/scrape.rb
@@ -1,43 +0,0 @@
-module Termtter::Client
- def self.scrape_group(group, t)
- members = configatron.plugins.group.groups[group] || []
- members.map {|member|
- t.get_user_timeline(member)
- }.flatten
- end
-
- def self.scrape_groups(t)
- groups = configatron.plugins.group.groups
- groups.map {|group|
- scrape_group(group, t)
- }.flatten
- end
-
- add_help 'scrape_group GROUPNAME', 'Get the group timeline'
- add_help 'scrape_groups', 'Get all groups timeline'
-
- add_command /^(?:scrape_group)\s+(.+)/ do |m, t|
- group_name = m[1].to_sym
- statuses = scrape_group(group_name, t)
- call_hooks(statuses, :pre_filter, t)
- puts "done"
- end
-
- add_command /^(?:scrape_groups)\s*$/ do |m, t|
- statuses = scrape_groups(t)
- call_hooks(statuses, :pre_filter, t)
- puts "done"
- end
-
- add_completion do |input|
- case input
- when /^(scrape_group)?\s+(.+)/
- find_group_candidates($2, "#{$1} %s") if defined? find_group_candidates
- when /^(scrape_group)\s+$/
- configatron.plugins.group.groups.keys
- else
- %w(scrape_group scrape_groups).grep(/^#{Regexp.quote input}/)
- end
- end
-
-end
View
22 lib/plugin/screen.rb
@@ -1,22 +0,0 @@
-module Termtter
- module Plugin
- module Screen
- def self.set_title(title)
- print "\033k#{title}\033\\"
- end
- end
- end
-end
-
-# Add below to your ~/.termtter
-#
-# require 'plugin/yonda'
-# require 'plugin/screen'
-# module Termtter::Client
-# add_hook do |statuses, event|
-# case event
-# when :update_friends_timeline, :plugin_yonda_yonda
-# Termtter::Plugin::Screen::set_title("termtter(#{public_storage[:unread_count]})")
-# end
-# end
-# end
View
4 lib/plugin/shell.rb
@@ -1,4 +0,0 @@
-module Termtter::Client
- add_help 'shell,sh', 'Start your shell'
- add_macro /^(?:shell|sh)\s*$/, "eval system ENV['SHELL'] || ENV['COMSPEC']"
-end
View
31 lib/plugin/sl.rb
@@ -1,31 +0,0 @@
-module Termtter::Client
- public_storage[:current] = ''
-
- add_macro /^sl\s*$/, 'eval system "sl"'
-
- add_help 'pwd', 'Show current direcroty'
- add_macro /^pwd\s*$/, 'eval public_storage[:current]'
-
- add_help 'ls', 'Show list in current directory'
- add_command /^ls\s*$/ do |m, t|
- call_commands "list #{public_storage[:current]}", t
- end
-
- add_help 'cd USER', 'Change current directory'
- add_command /^(?:cd\s+|\.\/)(.*)/ do |m, t|
- directory = m[1].strip
- directory = '' if /\~/ =~ directory
- public_storage[:current] = directory
- puts "=> #{directory}"
- end
- add_macro /^cd$/, 'eval public_storage[:current] = ""'
-
- add_completion do |input|
- case input
- when /^(cd\s+|\.\/)(.*)/
- find_user_candidates $2, "#{$1.gsub(/\s+/, ' ')}%s"
- else
- %w[ sl ls cd pwd ./ ].grep(/^#{Regexp.quote input}/)
- end
- end
-end
View
7 lib/plugin/spam.rb
@@ -1,7 +0,0 @@
-Termtter::Twitter.new(configatron.user_name, configatron.password).update_status('*super spam time*')
-module Termtter::Client
- clear_commands
- add_command /.+/ do |m, t|
- Thread.new { t.update_status(m[0]) }
- end
-end
View
238 lib/plugin/standard_plugins.rb
@@ -1,238 +0,0 @@
-require 'erb'
-
-module Termtter::Client
-
- # standard commands
-
- register_command(
- :name => :update, :aliases => [:u],
- :exec_proc => proc {|arg|
- text = ERB.new(arg).result(binding).gsub(/\n/, ' ')
- Termtter::API.twitter.update_status(text)
- puts "=> #{text}"
- },
- :completion_proc => proc {|cmd, args|
- if /(.*)@([^\s]*)$/ =~ args
- find_user_candidates $2, "#{cmd} #{$1}@%s"
- end
- }
- )
-
- register_command(
- :name => :direct, :aliases => [:d],
- :exec_proc => proc {|arg|
- if arg =~ /^([^\s]+)\s+(.*)\s*$/
- user, text = $1, $2
- Termtter::API.twitter.direct_message(user, text)
- puts "=> to:#{user} message:#{text}"
- end
- },
- :completion_proc => proc {|cmd, args|
- if args =~ /^([^\s]+)$/
- find_user_candidates $1, "#{cmd} %s"
- end
- }
- )
-
- register_command(
- :name => :profile, :aliases => [:p],
- :exec_proc => proc {|arg|
- user = Termtter::API.twitter.get_user_profile(arg)
- attrs = %w[ name screen_name url description profile_image_url location protected following
- friends_count followers_count statuses_count favourites_count
- id time_zone created_at utc_offset notifications
- ]
- label_width = attrs.map{|i|i.size}.max
- attrs.each do |attr|
- value = user.__send__(attr.to_sym)
- puts "#{attr.gsub('_', ' ').rjust(label_width)}: #{value}"
- end
- },
- :completion_proc => proc {|cmd, arg|
- find_user_candidates arg, "#{cmd} %s"
- }
- )
-
- register_command(
- :name => :list, :aliases => [:l],
- :exec_proc => proc {|arg|
- if arg
- call_hooks(Termtter::API.twitter.get_user_timeline(arg), :list_user_timeline)
- else
- call_hooks(Termtter::API.twitter.get_friends_timeline(), :list_friends_timeline)
- end
- },
- :completion_proc => proc {|cmd, arg|
- find_user_candidates arg, "#{cmd} %s"
- }
- )
-
- register_command(
- :name => :search, :aliases => [:s],
- :exec_proc => proc {|arg|
- call_hooks(Termtter::API.twitter.search(arg), :search)
- }
- )
-
- register_command(
- :name => :replies, :aliases => [:r],
- :exec_proc => proc {
- call_hooks(Termtter::API.twitter.replies(), :replies)
- }
- )
-
- register_command(
- :name => :show,
- :exec_proc => proc {|arg|
- id = arg.gsub(/.*:/, '')
- call_hooks(Termtter::API.twitter.show(id), :show)
- }
- )
-
- register_command(
- :name => :shows,
- :exec_proc => proc {|arg|
- id = arg.gsub(/.*:/, '')
- call_hooks(Termtter::API.twitter.show(id, true), :show)
- }
- )
-
- # TODO: Change colors when remaining_hits is low.
- # TODO: Simmulate remaining_hits.
- register_command(
- :name => :limit, :aliases => ['lm'],
- :exec_proc => proc {|arg|
- limit = Termtter::API.twitter.get_rate_limit_status
- remaining_time = "%dmin %dsec" % (limit.reset_time - Time.now).divmod(60)
- remaining_color =
- case limit.remaining_hits / limit.hourly_limit.to_f
- when 0.2..0.4 then :yellow
- when 0..0.2 then :red
- else :green
- end
- puts "=> #{color(limit.remaining_hits, remaining_color)}/#{limit.hourly_limit} until #{limit.reset_time} (#{remaining_time} remaining)"
- },
- :help => ["limit,lm", "Show the API limit status"]
- )
-
- register_command(
- :name => :pause,
- :exec_proc => proc {|arg| pause},
- :help => ["pause", "Pause updating"]
- )
-
- register_command(
- :name => :resume,
- :exec_proc => proc {|arg| resume},
- :help => ["resume", "Resume updating"]
- )
-
- register_command(
- :name => :exit, :aliases => ['e'],
- :exec_proc => proc {|arg| exit},
- :help => ['exit,e', 'Exit']
- )
-
- add_command /^(help|h)\s*$/ do |m, t|
- # TODO: migrate to use Termtter::Command#help
- helps = [
- ["help,h", "Print this help message"],
- ["list,l", "List the posts in your friends timeline"],
- ["list,l USERNAME", "List the posts in the the given user's timeline"],
- ["update,u TEXT", "Post a new message"],
- ["direct,d @USERNAME TEXT", "Send direct message"],
- ["profile,p USERNAME", "Show user's profile"],
- ["replies,r", "List the most recent @replies for the authenticating user"],
- ["search,s TEXT", "Search for Twitter"],
- ["show ID", "Show a single status"]
- ]
- helps += @@helps
- helps += @@new_commands.map {|name, command| command.help}
- helps.compact!
- puts formatted_help(helps)
- end
-
- add_command /^eval\s+(.*)$/ do |m, t|
- begin
- result = eval(m[1]) unless m[1].empty?
- puts "=> #{result.inspect}"
- rescue SyntaxError => e
- puts e
- end
- end
-
- add_command /^!(!)?\s*(.*)$/ do |m, t|
- begin
- result = `#{m[2]}` unless m[2].empty?
- unless m[1].nil? || result.empty?
- t.update_status(result.gsub("\n", " "))
- end
- puts "=> #{result}"
- rescue => e
- puts e
- end
- end
-
- def self.formatted_help(helps)
- helps = helps.sort_by{|help| help[0]}
- width = helps.map {|n, d| n.size }.max
- space = 3
- helps.map {|name, desc|
- name.to_s.ljust(width + space) + desc.to_s
- }.join("\n")
- end
-
- # completion for standard commands
-
- require 'set'
- public_storage[:users] ||= Set.new
- public_storage[:status_ids] ||= Set.new
-
- add_hook do |statuses, event, t|
- statuses.each do |s|
- public_storage[:users].add(s.user_screen_name)
- public_storage[:users] += s.text.scan(/@([a-zA-Z_0-9]*)/).flatten
- public_storage[:status_ids].add(s.id.to_s)
- public_storage[:status_ids].add(s.in_reply_to_status_id.to_s) if s.in_reply_to_status_id
- end
- end
-
- def self.find_status_id_candidates(a, b, u = nil)
- candidates = public_storage[:status_ids].to_a
- if u && c = public_storage[:log].select {|s| s.user_screen_name == u }.map {|s| s.id.to_s }
- candidates = c unless c.empty?
- end
- if a.empty?
- candidates
- else
- candidates.grep(/#{Regexp.quote a}/)
- end.
- map {|u| b % u }
- end
-
- def self.find_user_candidates(a, b)
- if a.nil? || a.empty?
- public_storage[:users].to_a
- else
- public_storage[:users].grep(/^#{Regexp.quote a}/i)
- end.
- map {|u| b % u }
- end
-
- add_completion do |input|
- standard_commands = %w[exit help list pause profile update direct resume replies search show limit]
- case input
- when /^show(s)?\s+(([\w\d]+):)?\s*(.*)/