termtter 0.8.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.
- data/History.txt +4 -0
- data/README.rdoc +97 -0
- data/Rakefile +46 -0
- data/bin/kill_termtter +22 -0
- data/bin/termtter +7 -0
- data/lib/filter/en2ja.rb +11 -0
- data/lib/filter/english.rb +8 -0
- data/lib/filter/expand-tinyurl.rb +24 -0
- data/lib/filter/fib.rb +15 -0
- data/lib/filter/ignore.rb +19 -0
- data/lib/filter/reply.rb +8 -0
- data/lib/filter/reverse.rb +13 -0
- data/lib/filter/url_addspace.rb +16 -0
- data/lib/filter/yhara.rb +20 -0
- data/lib/plugin/april_fool.rb +15 -0
- data/lib/plugin/bomb.rb +29 -0
- data/lib/plugin/clear.rb +14 -0
- data/lib/plugin/confirm.rb +9 -0
- data/lib/plugin/cool.rb +10 -0
- data/lib/plugin/devel.rb +13 -0
- data/lib/plugin/english.rb +59 -0
- data/lib/plugin/erb.rb +17 -0
- data/lib/plugin/favorite.rb +75 -0
- data/lib/plugin/fib.rb +8 -0
- data/lib/plugin/filter.rb +69 -0
- data/lib/plugin/follow.rb +56 -0
- data/lib/plugin/graduatter.rb +9 -0
- data/lib/plugin/grass.rb +27 -0
- data/lib/plugin/group.rb +60 -0
- data/lib/plugin/growl.rb +62 -0
- data/lib/plugin/hatebu.rb +59 -0
- data/lib/plugin/history.rb +82 -0
- data/lib/plugin/keyword.rb +18 -0
- data/lib/plugin/log.rb +63 -0
- data/lib/plugin/modify_arg_hook_sample.rb +7 -0
- data/lib/plugin/msagent.rb +26 -0
- data/lib/plugin/multi_reply.rb +36 -0
- data/lib/plugin/notify-send.rb +17 -0
- data/lib/plugin/otsune.rb +21 -0
- data/lib/plugin/outputz.rb +35 -0
- data/lib/plugin/pause.rb +3 -0
- data/lib/plugin/plugin.rb +53 -0
- data/lib/plugin/post_exec_hook_sample.rb +9 -0
- data/lib/plugin/pre_exec_hook_sample.rb +9 -0
- data/lib/plugin/primes.rb +23 -0
- data/lib/plugin/quicklook.rb +38 -0
- data/lib/plugin/reblog.rb +40 -0
- data/lib/plugin/reload.rb +3 -0
- data/lib/plugin/say.rb +24 -0
- data/lib/plugin/scrape.rb +41 -0
- data/lib/plugin/screen.rb +24 -0
- data/lib/plugin/shell.rb +14 -0
- data/lib/plugin/sl.rb +48 -0
- data/lib/plugin/spam.rb +9 -0
- data/lib/plugin/standard_plugins.rb +269 -0
- data/lib/plugin/stdout.rb +62 -0
- data/lib/plugin/system_status.rb +33 -0
- data/lib/plugin/translation.rb +28 -0
- data/lib/plugin/update_editor.rb +53 -0
- data/lib/plugin/uri-open.rb +69 -0
- data/lib/plugin/wassr_post.rb +22 -0
- data/lib/plugin/yhara.rb +148 -0
- data/lib/plugin/yonda.rb +20 -0
- data/lib/termtter/api.rb +14 -0
- data/lib/termtter/client.rb +399 -0
- data/lib/termtter/command.rb +77 -0
- data/lib/termtter/connection.rb +39 -0
- data/lib/termtter/hook.rb +18 -0
- data/lib/termtter/status.rb +26 -0
- data/lib/termtter/task.rb +16 -0
- data/lib/termtter/task_manager.rb +116 -0
- data/lib/termtter/twitter.rb +173 -0
- data/lib/termtter/user.rb +13 -0
- data/lib/termtter/version.rb +3 -0
- data/lib/termtter.rb +157 -0
- data/spec/plugin/cool_spec.rb +10 -0
- data/spec/plugin/fib_spec.rb +16 -0
- data/spec/plugin/filter_spec.rb +18 -0
- data/spec/plugin/plugin_spec.rb +25 -0
- data/spec/plugin/shell_spec.rb +10 -0
- data/spec/plugin/spam_spec.rb +17 -0
- data/spec/plugin/standard_plugins_spec.rb +31 -0
- data/spec/spec_helper.rb +4 -0
- data/spec/termtter/client_spec.rb +175 -0
- data/spec/termtter/command_spec.rb +161 -0
- data/spec/termtter/task_manager_spec.rb +78 -0
- data/spec/termtter/task_spec.rb +22 -0
- data/spec/termtter/user_spec.rb +27 -0
- data/spec/termtter_spec.rb +43 -0
- data/test/friends_timeline.json +5 -0
- data/test/search.json +8 -0
- data/test/test_termtter.rb +86 -0
- metadata +177 -0
| @@ -0,0 +1,56 @@ | |
| 1 | 
            +
            # -*- coding: utf-8 -*-
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Termtter::Client
         | 
| 4 | 
            +
              register_command(
         | 
| 5 | 
            +
                :name => :follow, :aliases => [],
         | 
| 6 | 
            +
                :exec_proc => lambda {|arg|
         | 
| 7 | 
            +
                  if arg =~ /^(\w+)/
         | 
| 8 | 
            +
                    res = Termtter::API::twitter.social($1.strip, :follow)
         | 
| 9 | 
            +
                    if res.code == '200'
         | 
| 10 | 
            +
                      puts "Followed user @#{$1}"
         | 
| 11 | 
            +
                    else
         | 
| 12 | 
            +
                      puts "Failed: #{res}"
         | 
| 13 | 
            +
                    end
         | 
| 14 | 
            +
                  end
         | 
| 15 | 
            +
                },
         | 
| 16 | 
            +
                :completion_proc => lambda {|cmd, args|
         | 
| 17 | 
            +
                  find_user_candidates args, "#{cmd} %s"
         | 
| 18 | 
            +
                },
         | 
| 19 | 
            +
            	:help => ['follow USER', 'Follow user']
         | 
| 20 | 
            +
              )
         | 
| 21 | 
            +
             | 
| 22 | 
            +
              register_command(
         | 
| 23 | 
            +
                :name => :leave, :aliases => [],
         | 
| 24 | 
            +
                :exec_proc => lambda {|arg|
         | 
| 25 | 
            +
                  if arg =~ /^(\w+)/
         | 
| 26 | 
            +
                    res = Termtter::API::twitter.social($1.strip, :leave)
         | 
| 27 | 
            +
                    if res.code == '200'
         | 
| 28 | 
            +
                      puts "Leaved user @#{$1}"
         | 
| 29 | 
            +
                    else
         | 
| 30 | 
            +
                      puts "Failed: #{res}"
         | 
| 31 | 
            +
                    end
         | 
| 32 | 
            +
                  end
         | 
| 33 | 
            +
                },
         | 
| 34 | 
            +
                :completion_proc => lambda {|cmd, args|
         | 
| 35 | 
            +
                  find_user_candidates args, "#{cmd} %s"
         | 
| 36 | 
            +
                },
         | 
| 37 | 
            +
            	:help => ['leave USER', 'Leave user']
         | 
| 38 | 
            +
              )
         | 
| 39 | 
            +
            end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
            module Termtter
         | 
| 42 | 
            +
              class Twitter
         | 
| 43 | 
            +
                def social(user, type)
         | 
| 44 | 
            +
                  type =
         | 
| 45 | 
            +
                    case type.to_sym
         | 
| 46 | 
            +
                    when :follow then 'create'
         | 
| 47 | 
            +
                    when :leave  then 'destroy'
         | 
| 48 | 
            +
                    end
         | 
| 49 | 
            +
                  uri = "#{@connection.protocol}://twitter.com/friendships/#{type}/#{user}.json"
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                  @connection.start('twitter.com', @connection.port) do |http|
         | 
| 52 | 
            +
                    http.request(post_request(uri))
         | 
| 53 | 
            +
                  end
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
              end
         | 
| 56 | 
            +
            end
         | 
| @@ -0,0 +1,9 @@ | |
| 1 | 
            +
            # -*- coding: utf-8 -*-
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            twitter = Termtter::Twitter.new(configatron.user_name, configatron.password)
         | 
| 4 | 
            +
            Thread.start do
         | 
| 5 | 
            +
              100.times do |i|
         | 
| 6 | 
            +
                twitter.update_status(
         | 
| 7 | 
            +
                  "I decided not to use twitter so as not to leave university before I complete the dissertation#{i.odd? ? '!' : '.'}")
         | 
| 8 | 
            +
              end
         | 
| 9 | 
            +
            end
         | 
    
        data/lib/plugin/grass.rb
    ADDED
    
    | @@ -0,0 +1,27 @@ | |
| 1 | 
            +
            # -*- coding: utf-8 -*-
         | 
| 2 | 
            +
            module Termtter
         | 
| 3 | 
            +
              module Client
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                configatron.plugins.grass.set_default(:rate, 0)
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                register_command(
         | 
| 8 | 
            +
                  :name => :w, :aliases => [:grass],
         | 
| 9 | 
            +
                  :exec_proc => lambda {|arg|
         | 
| 10 | 
            +
                    arg, rate = arg.split(/ /)
         | 
| 11 | 
            +
                    count = arg =~ /^[0-9]+$/ ? arg.to_i : 3
         | 
| 12 | 
            +
                    rate ||= configatron.plugins.grass.rate
         | 
| 13 | 
            +
                    grow = (count * rate.to_i).quo(100).round
         | 
| 14 | 
            +
                    grasses = ('w' * (count-grow) + 'W' * grow).split(//).shuffle.join
         | 
| 15 | 
            +
                    call_commands("update #{grasses}")
         | 
| 16 | 
            +
                  },
         | 
| 17 | 
            +
                  :help => ['grass, w', 'Grass it!']
         | 
| 18 | 
            +
                )
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
            end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
            # usage
         | 
| 23 | 
            +
            # > w 10
         | 
| 24 | 
            +
            # => wwwwwwwwww
         | 
| 25 | 
            +
            #
         | 
| 26 | 
            +
            # see also
         | 
| 27 | 
            +
            #   http://d.hatena.ne.jp/tomisima/20090204/1233762301
         | 
    
        data/lib/plugin/group.rb
    ADDED
    
    | @@ -0,0 +1,60 @@ | |
| 1 | 
            +
            # -*- coding: utf-8 -*-
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Termtter
         | 
| 4 | 
            +
              class Status
         | 
| 5 | 
            +
                def is_member?(group = nil)
         | 
| 6 | 
            +
                  if group
         | 
| 7 | 
            +
                    configatron.plugins.group.groups[group].include? self.user_screen_name
         | 
| 8 | 
            +
                  else
         | 
| 9 | 
            +
                    configatron.plugins.group.groups.values.flatten.include? self.user_screen_name
         | 
| 10 | 
            +
                  end
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
            end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            module Termtter::Client
         | 
| 16 | 
            +
              configatron.plugins.group.
         | 
| 17 | 
            +
                set_default(:groups, {})
         | 
| 18 | 
            +
             | 
| 19 | 
            +
              def self.find_group_candidates(a, b)
         | 
| 20 | 
            +
                configatron.plugins.group.groups.keys.map {|k| k.to_s}.
         | 
| 21 | 
            +
                  grep(/^#{Regexp.quote a}/).
         | 
| 22 | 
            +
                  map {|u| b % u }
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
              register_command(
         | 
| 26 | 
            +
               :name => :group,
         | 
| 27 | 
            +
               :aliases => [:g],
         | 
| 28 | 
            +
               :exec_proc => lambda {|arg|
         | 
| 29 | 
            +
                 unless arg.empty?
         | 
| 30 | 
            +
                   group_name = arg.to_sym
         | 
| 31 | 
            +
                   if group_name == :all
         | 
| 32 | 
            +
                     group = configatron.plugins.group.groups.values.flatten.uniq
         | 
| 33 | 
            +
                   else
         | 
| 34 | 
            +
                     group = configatron.plugins.group.groups[group_name]
         | 
| 35 | 
            +
                   end
         | 
| 36 | 
            +
                   statuses = group ? public_storage[:log].select { |s|
         | 
| 37 | 
            +
                     group.include?(s.user_screen_name) 
         | 
| 38 | 
            +
                   } : []
         | 
| 39 | 
            +
                   call_hooks(statuses, :search)
         | 
| 40 | 
            +
                 else
         | 
| 41 | 
            +
                   configatron.plugins.group.groups.each_pair do |key, value|
         | 
| 42 | 
            +
                     puts "#{key}: #{value.join(',')}"
         | 
| 43 | 
            +
                   end
         | 
| 44 | 
            +
                 end
         | 
| 45 | 
            +
               },
         | 
| 46 | 
            +
               :completion_proc => lambda {|cmd, arg|
         | 
| 47 | 
            +
                 find_group_candidates arg, "#{cmd} %s"
         | 
| 48 | 
            +
                               },
         | 
| 49 | 
            +
               :help => ['group,g GROUPNAME', 'Filter by group members']
         | 
| 50 | 
            +
               )
         | 
| 51 | 
            +
              
         | 
| 52 | 
            +
            end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
            # group.rb
         | 
| 55 | 
            +
            #   plugin 'group'
         | 
| 56 | 
            +
            #   configatron.plugins.group.groups = {
         | 
| 57 | 
            +
            #     :rits => %w(hakobe isano hitode909)
         | 
| 58 | 
            +
            #   }
         | 
| 59 | 
            +
            # NOTE: group.rb needs plugin/log
         | 
| 60 | 
            +
             | 
    
        data/lib/plugin/growl.rb
    ADDED
    
    | @@ -0,0 +1,62 @@ | |
| 1 | 
            +
            # -*- coding: utf-8 -*-
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'tmpdir'
         | 
| 4 | 
            +
            require 'open-uri'
         | 
| 5 | 
            +
            require 'uri'
         | 
| 6 | 
            +
            require 'fileutils'
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            begin
         | 
| 9 | 
            +
              require 'ruby-growl'
         | 
| 10 | 
            +
              growl = Growl.new "localhost", "termtter", "termtter status notification"
         | 
| 11 | 
            +
            rescue LoadError
         | 
| 12 | 
            +
              growl = nil
         | 
| 13 | 
            +
            end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            configatron.plugins.growl.set_default(:icon_cache_dir, "#{Dir.tmpdir}/termtter-icon-cache-dir")
         | 
| 16 | 
            +
            FileUtils.mkdir_p(configatron.plugins.growl.icon_cache_dir) unless File.exist?(configatron.plugins.growl.icon_cache_dir)
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            def get_icon_path(s)
         | 
| 19 | 
            +
              cache_file = "%s/%s%s" % [  configatron.plugins.growl.icon_cache_dir, 
         | 
| 20 | 
            +
                                          s.user_screen_name, 
         | 
| 21 | 
            +
                                          File.extname(s.user_profile_image_url)  ]
         | 
| 22 | 
            +
              if File.exist?(cache_file) && (File.atime(cache_file) + 24*60*60) > Time.now
         | 
| 23 | 
            +
                return cache_file
         | 
| 24 | 
            +
              else
         | 
| 25 | 
            +
                Thread.new do
         | 
| 26 | 
            +
                  File.open(cache_file, "wb") do |f|
         | 
| 27 | 
            +
                    f << open(URI.escape(s.user_profile_image_url)).read
         | 
| 28 | 
            +
                  end
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
                return nil
         | 
| 31 | 
            +
              end
         | 
| 32 | 
            +
            end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
            queue = []
         | 
| 35 | 
            +
            Thread.new do
         | 
| 36 | 
            +
              loop do
         | 
| 37 | 
            +
                begin
         | 
| 38 | 
            +
                  if s = queue.pop
         | 
| 39 | 
            +
                    unless growl
         | 
| 40 | 
            +
                      arg = ['growlnotify', s.user_screen_name, '-m', s.text.gsub("\n",''), '-n', 'termtter']
         | 
| 41 | 
            +
                      #icon_path = get_icon_path(s)
         | 
| 42 | 
            +
                      #arg += ['--image', icon_path] if icon_path
         | 
| 43 | 
            +
                      system *arg
         | 
| 44 | 
            +
                    else
         | 
| 45 | 
            +
                      growl.notify "termtter status notification", s.text, s.user_screen_name
         | 
| 46 | 
            +
                    end
         | 
| 47 | 
            +
                  end
         | 
| 48 | 
            +
                rescue => e
         | 
| 49 | 
            +
                  puts e
         | 
| 50 | 
            +
                  puts e.backtrace.join("\n")
         | 
| 51 | 
            +
                end
         | 
| 52 | 
            +
                sleep 0.1
         | 
| 53 | 
            +
              end
         | 
| 54 | 
            +
            end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
            Termtter::Client.add_hook do |statuses, event|
         | 
| 57 | 
            +
              if !statuses.empty? && event == :update_friends_timeline
         | 
| 58 | 
            +
                statuses.reverse.each do |s|
         | 
| 59 | 
            +
                  queue << s
         | 
| 60 | 
            +
                end
         | 
| 61 | 
            +
              end
         | 
| 62 | 
            +
            end
         | 
| @@ -0,0 +1,59 @@ | |
| 1 | 
            +
            # -*- coding: utf-8 -*-
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'rubygems'
         | 
| 4 | 
            +
            require 'atomutil'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            module Termtter::Client
         | 
| 7 | 
            +
              register_command(
         | 
| 8 | 
            +
                :name => :hatebu, :aliases => [],
         | 
| 9 | 
            +
                :exec_proc => lambda {|arg|
         | 
| 10 | 
            +
                  if arg =~ /^(\d+)(.*)$/
         | 
| 11 | 
            +
                    id = $1.strip
         | 
| 12 | 
            +
                    comment = $2.strip
         | 
| 13 | 
            +
                    statuses = public_storage[:log].select { |s| s.id == id }
         | 
| 14 | 
            +
                    unless statuses.empty?
         | 
| 15 | 
            +
                      status = statuses.first
         | 
| 16 | 
            +
                    else
         | 
| 17 | 
            +
                      status = t.show(id).first
         | 
| 18 | 
            +
                    end
         | 
| 19 | 
            +
                    auth = auth = Atompub::Auth::Wsse.new({
         | 
| 20 | 
            +
                        :username => configatron.plugins.hatebu.username,
         | 
| 21 | 
            +
                        :password => configatron.plugins.hatebu.password,
         | 
| 22 | 
            +
                    })
         | 
| 23 | 
            +
                    link = Atom::Link.new({
         | 
| 24 | 
            +
                       :href => "http://twitter.com/#{status.user_screen_name}/status/#{status.id}",
         | 
| 25 | 
            +
                       :rel => 'related',
         | 
| 26 | 
            +
                       :type => 'text/html',
         | 
| 27 | 
            +
                    })
         | 
| 28 | 
            +
                    entry = Atom::Entry.new({
         | 
| 29 | 
            +
                        :link => link,
         | 
| 30 | 
            +
                        :title => 'dummy',
         | 
| 31 | 
            +
                        :summary => comment,
         | 
| 32 | 
            +
                    })
         | 
| 33 | 
            +
                    req = Net::HTTP::Post.new 'http://b.hatena.ne.jp/atom/post'
         | 
| 34 | 
            +
                    req['User-Agent'] = 'Mozilla/5.0'
         | 
| 35 | 
            +
                    req['Content-Type'] = 'application/atom+xml'
         | 
| 36 | 
            +
                    req['Slug'] = 'termtter'
         | 
| 37 | 
            +
                    req.body = entry.to_s
         | 
| 38 | 
            +
                    auth.authorize(req)
         | 
| 39 | 
            +
                    Net::HTTP.start('b.hatena.ne.jp', 80) do |http|
         | 
| 40 | 
            +
                      res = http.request(req)
         | 
| 41 | 
            +
                    end
         | 
| 42 | 
            +
                  end
         | 
| 43 | 
            +
                },
         | 
| 44 | 
            +
                :completion_proc => lambda {|cmd, args|
         | 
| 45 | 
            +
                  if args =~ /^(\d*)$/
         | 
| 46 | 
            +
                    find_status_id_candidates $1, "#{cmd} %s"
         | 
| 47 | 
            +
                  end
         | 
| 48 | 
            +
                },
         | 
| 49 | 
            +
            	:help => ['hatebu ID', 'Hatena bookmark a status']
         | 
| 50 | 
            +
              )
         | 
| 51 | 
            +
            end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
            # hatebu.rb
         | 
| 54 | 
            +
            # hatena bookmark it!
         | 
| 55 | 
            +
            #
         | 
| 56 | 
            +
            # configatron.plugins.hatebu.username = 'your-username-on-hatena'
         | 
| 57 | 
            +
            # configatron.plugins.hatebu.password = 'your-password-on-hatena'
         | 
| 58 | 
            +
            #
         | 
| 59 | 
            +
            #   hatebu 1114860346 [termtter][����͂�����]mattn++
         | 
| @@ -0,0 +1,82 @@ | |
| 1 | 
            +
            # -*- coding: utf-8 -*-
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'zlib'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            configatron.plugins.history.
         | 
| 6 | 
            +
              set_default(:filename, '~/.termtter_history')
         | 
| 7 | 
            +
            configatron.plugins.history.
         | 
| 8 | 
            +
              set_default(:keys, [:log, :users, :status_ids])
         | 
| 9 | 
            +
            configatron.plugins.history.
         | 
| 10 | 
            +
              set_default(:max_of_history, 100)
         | 
| 11 | 
            +
            configatron.plugins.history.
         | 
| 12 | 
            +
              set_default(:enable_autosave, true)
         | 
| 13 | 
            +
            configatron.plugins.history.
         | 
| 14 | 
            +
              set_default(:autosave_interval, 3600)
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            module Termtter::Client
         | 
| 17 | 
            +
              def self.load_history
         | 
| 18 | 
            +
                filename = File.expand_path(configatron.plugins.history.filename)
         | 
| 19 | 
            +
                keys = configatron.plugins.history.keys
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                if File.exist?(filename)
         | 
| 22 | 
            +
                  begin
         | 
| 23 | 
            +
                    history = Marshal.load Zlib::Inflate.inflate(File.read(filename))
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
                  if history
         | 
| 26 | 
            +
                    keys.each do |key|
         | 
| 27 | 
            +
                      public_storage[key] = history[key] if history[key]
         | 
| 28 | 
            +
                    end
         | 
| 29 | 
            +
                    Readline::HISTORY.push *history[:history] if history[:history]
         | 
| 30 | 
            +
                    puts "history loaded(#{File.size(filename)/1000}kb)"
         | 
| 31 | 
            +
                  end
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
              end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
              def self.save_history
         | 
| 36 | 
            +
                filename = File.expand_path(configatron.plugins.history.filename)
         | 
| 37 | 
            +
                keys = configatron.plugins.history.keys
         | 
| 38 | 
            +
                history = { }
         | 
| 39 | 
            +
                keys.each do |key|
         | 
| 40 | 
            +
                  history[key] = public_storage[key]
         | 
| 41 | 
            +
                end
         | 
| 42 | 
            +
                max_of_history = configatron.plugins.history.max_of_history
         | 
| 43 | 
            +
                history[:history] = Readline::HISTORY.to_a.reverse.uniq.reverse
         | 
| 44 | 
            +
                if history[:history].size > max_of_history
         | 
| 45 | 
            +
                  history[:history] = history[:history][-max_of_history..-1]
         | 
| 46 | 
            +
                end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                File.open(filename, 'w') do |f|
         | 
| 49 | 
            +
                  f.write Zlib::Deflate.deflate(Marshal.dump(history))
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
                puts "history saved(#{File.size(filename)/1000}kb)"
         | 
| 52 | 
            +
              end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
              add_hook do |statuses, event|
         | 
| 55 | 
            +
                case event
         | 
| 56 | 
            +
                when :initialize
         | 
| 57 | 
            +
                  load_history
         | 
| 58 | 
            +
                when :exit
         | 
| 59 | 
            +
                  save_history
         | 
| 60 | 
            +
                end
         | 
| 61 | 
            +
              end
         | 
| 62 | 
            +
             | 
| 63 | 
            +
              if configatron.plugins.history.enable_autosave
         | 
| 64 | 
            +
                Termtter::Client.add_task(:interval => configatron.plugins.history.autosave_interval,
         | 
| 65 | 
            +
                                          :after => configatron.plugins.history.autosave_interval) do
         | 
| 66 | 
            +
                  save_history
         | 
| 67 | 
            +
                end
         | 
| 68 | 
            +
              end
         | 
| 69 | 
            +
             | 
| 70 | 
            +
              register_command(
         | 
| 71 | 
            +
               :name => :save,
         | 
| 72 | 
            +
               :exec_proc => lambda{|arg|
         | 
| 73 | 
            +
                 save_history
         | 
| 74 | 
            +
               },
         | 
| 75 | 
            +
               :help => ['save', 'Save hisory']
         | 
| 76 | 
            +
               )
         | 
| 77 | 
            +
             | 
| 78 | 
            +
              
         | 
| 79 | 
            +
            end
         | 
| 80 | 
            +
             | 
| 81 | 
            +
            # history.rb
         | 
| 82 | 
            +
            #   save log to file
         | 
| @@ -0,0 +1,18 @@ | |
| 1 | 
            +
            # -*- coding: utf-8 -*-
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            configatron.set_default('plugins.keyword.keywords', [])
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module Termtter
         | 
| 6 | 
            +
              class Status
         | 
| 7 | 
            +
                def has_keyword?
         | 
| 8 | 
            +
                  configatron.plugins.keyword.keywords.find { |k| k === self.text }
         | 
| 9 | 
            +
                end
         | 
| 10 | 
            +
                alias :has_keyword :has_keyword?
         | 
| 11 | 
            +
              end
         | 
| 12 | 
            +
            end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            # keyword.rb
         | 
| 15 | 
            +
            #   provides a keyword watching method
         | 
| 16 | 
            +
            # example config
         | 
| 17 | 
            +
            #   configatron.plugins.stdout.timeline_format = '<%= color(time, 90) %> <%= color(status, s.has_keyword ? 4 : status_color) %> <%= color(id, 90) %>'
         | 
| 18 | 
            +
            #   configatron.plugins.keyword.keywords = [ /motemen/ ]
         | 
    
        data/lib/plugin/log.rb
    ADDED
    
    | @@ -0,0 +1,63 @@ | |
| 1 | 
            +
            # -*- coding: utf-8 -*-
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Termtter::Client
         | 
| 4 | 
            +
              public_storage[:log] = []
         | 
| 5 | 
            +
              configatron.plugins.log.set_default('max_size', 1/0.0)
         | 
| 6 | 
            +
              configatron.plugins.log.set_default('print_max_size', 30)
         | 
| 7 | 
            +
             | 
| 8 | 
            +
              add_hook do |statuses, event|
         | 
| 9 | 
            +
                case event
         | 
| 10 | 
            +
                when :pre_filter
         | 
| 11 | 
            +
                  public_storage[:log] += statuses
         | 
| 12 | 
            +
                  max_size = configatron.plugins.log.max_size
         | 
| 13 | 
            +
                  if public_storage[:log].size > max_size
         | 
| 14 | 
            +
                    public_storage[:log] = public_storage[:log][-max_size..-1]
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
                  public_storage[:log] = public_storage[:log].uniq.sort_by{|a| a.created_at} if statuses.first
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
              register_command(
         | 
| 21 | 
            +
               :name => :log,
         | 
| 22 | 
            +
               :exec_proc => lambda{|arg|
         | 
| 23 | 
            +
                 if arg.empty?
         | 
| 24 | 
            +
                   # log
         | 
| 25 | 
            +
                   statuses = public_storage[:log]
         | 
| 26 | 
            +
                   print_max = configatron.plugins.log.print_max_size
         | 
| 27 | 
            +
                   print_max = 0 if statuses.size < print_max
         | 
| 28 | 
            +
                   call_hooks(statuses[-print_max..-1], :search)
         | 
| 29 | 
            +
                 else
         | 
| 30 | 
            +
                   # log (user) (max)
         | 
| 31 | 
            +
                   vars = arg.split(' ')
         | 
| 32 | 
            +
                   print_max = vars.last =~ /^\d+$/ ? vars.pop.to_i : configatron.plugins.log.print_max_size
         | 
| 33 | 
            +
                   id = vars
         | 
| 34 | 
            +
                   statuses = id.first ? public_storage[:log].select{ |s| id.include? s.user_screen_name} : public_storage[:log]
         | 
| 35 | 
            +
                   print_max = 0 if statuses.size < print_max
         | 
| 36 | 
            +
                   call_hooks(statuses[-print_max..-1], :search)
         | 
| 37 | 
            +
                 end
         | 
| 38 | 
            +
               },
         | 
| 39 | 
            +
               :completion_proc => lambda {|cmd, arg|
         | 
| 40 | 
            +
                 find_user_candidates arg, "#{cmd} %s"
         | 
| 41 | 
            +
               },
         | 
| 42 | 
            +
               :help => [ 'log (USER(S)) (MAX)', 'Show local log of the user(s)']
         | 
| 43 | 
            +
               )
         | 
| 44 | 
            +
             | 
| 45 | 
            +
              register_command(
         | 
| 46 | 
            +
               :name => :search_log, :aliases => [:sl],
         | 
| 47 | 
            +
               :exec_proc => lambda{|arg|
         | 
| 48 | 
            +
                unless arg.strip.empty?
         | 
| 49 | 
            +
                  pat = Regexp.new arg
         | 
| 50 | 
            +
                  statuses = public_storage[:log].select { |s| s.text =~ pat }
         | 
| 51 | 
            +
                  call_hooks(statuses, :search)
         | 
| 52 | 
            +
                 end
         | 
| 53 | 
            +
               },
         | 
| 54 | 
            +
               :help => [ 'search_log WORD', 'Search log for WORD' ]
         | 
| 55 | 
            +
               )
         | 
| 56 | 
            +
             | 
| 57 | 
            +
              add_command %r'^/(.+)' do |m, t|
         | 
| 58 | 
            +
                warn '/WORD command will be removed. Use search_log command instead.'
         | 
| 59 | 
            +
                pat = Regexp.new(m[1])
         | 
| 60 | 
            +
                statuses = public_storage[:log].select { |s| s.text =~ pat }
         | 
| 61 | 
            +
                call_hooks(statuses, :search, t)
         | 
| 62 | 
            +
              end
         | 
| 63 | 
            +
            end
         | 
| @@ -0,0 +1,26 @@ | |
| 1 | 
            +
            # -*- coding: utf-8 -*-
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            raise 'msagent.rb runs only in windows' if RUBY_PLATFORM.downcase !~ /mswin(?!ce)|mingw|bccwin/
         | 
| 4 | 
            +
            require 'win32ole'
         | 
| 5 | 
            +
            require 'kconv'
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            agent = WIN32OLE.new('Agent.Control.2')
         | 
| 8 | 
            +
            agent.connected = true
         | 
| 9 | 
            +
            agent.characters.load("Merlin", ENV['WINDIR'] + "\\msagent\\chars\\Merlin.acs")
         | 
| 10 | 
            +
            achar = agent.characters.character("Merlin")
         | 
| 11 | 
            +
            achar.languageID = 0x411
         | 
| 12 | 
            +
            achar.show
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            Termtter::Client.add_hook do |statuses, event, t|
         | 
| 15 | 
            +
              if event == :exit
         | 
| 16 | 
            +
                achar.hide   
         | 
| 17 | 
            +
                GC.start
         | 
| 18 | 
            +
              elsif !statuses.empty? && event == :update_friends_timeline
         | 
| 19 | 
            +
                statuses.reverse.each do |s|
         | 
| 20 | 
            +
                  req = achar.speak("#{s.user_screen_name}: #{s.text}".tosjis)
         | 
| 21 | 
            +
                  sleep 3
         | 
| 22 | 
            +
                  WIN32OLE_EVENT.message_loop
         | 
| 23 | 
            +
                  achar.stop(req)
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
            end
         | 
| @@ -0,0 +1,36 @@ | |
| 1 | 
            +
            # -*- coding: utf-8 -*-
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Termtter::Client
         | 
| 4 | 
            +
              add_help 'multi_reply, mp TEXT', 'reply to multi user'
         | 
| 5 | 
            +
              add_command /^(multi_reply|mr)\s+(.*)/ do |m, t|
         | 
| 6 | 
            +
                text = ERB.new(m[2]).result(binding).gsub(/\n/, ' ')
         | 
| 7 | 
            +
                unless text.empty?
         | 
| 8 | 
            +
                  #targets, _, msg = text.match /(@(.+))*\s+(.+)/
         | 
| 9 | 
            +
                  #targets.split(/\s+/).
         | 
| 10 | 
            +
                  #  map {|u| "#{u} #{msg}" }.
         | 
| 11 | 
            +
                  #  each do |post|
         | 
| 12 | 
            +
                  #    t.update_status(post)
         | 
| 13 | 
            +
                  #    puts "=> #{post}"
         | 
| 14 | 
            +
                  #  end
         | 
| 15 | 
            +
                  /(@(.+))*\s+(.+)/ =~ text
         | 
| 16 | 
            +
                  if $1
         | 
| 17 | 
            +
                    msg = $3
         | 
| 18 | 
            +
                    text = $1.split(/\s+/).map {|u| "#{u} #{msg}" }
         | 
| 19 | 
            +
                  end
         | 
| 20 | 
            +
                  Array(text).each do |post|
         | 
| 21 | 
            +
                    t.update_status(post)
         | 
| 22 | 
            +
                    puts "=> #{post}"
         | 
| 23 | 
            +
                  end
         | 
| 24 | 
            +
                  #
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
              end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
              add_completion do |input|
         | 
| 29 | 
            +
                case input
         | 
| 30 | 
            +
                when /^(multi_reply|mr)\s+(.*)@([^\s]*)$/
         | 
| 31 | 
            +
                  find_user_candidates $3, "#{$1} #{$2}@%s"
         | 
| 32 | 
            +
                else
         | 
| 33 | 
            +
                  %w[ mreply mp ].grep(/^#{Regexp.quote input}/)
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
              end
         | 
| 36 | 
            +
            end
         | 
| @@ -0,0 +1,17 @@ | |
| 1 | 
            +
            # -*- coding: utf-8 -*-
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            Termtter::Client.add_hook do |statuses, event|
         | 
| 4 | 
            +
              if !statuses.empty? && event == :update_friends_timeline
         | 
| 5 | 
            +
                max = 10
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                text = statuses.take(max).map {|s|
         | 
| 8 | 
            +
                  status_text = CGI.escapeHTML(s.text)
         | 
| 9 | 
            +
                  status_text.gsub!(%r{https?://[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+},'<a href="\0">\0</a>')
         | 
| 10 | 
            +
                  "<b>#{s.user_screen_name}:</b> <span font=\"9.0\">#{status_text}</span>"
         | 
| 11 | 
            +
                }.join("\n")
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                text << %Q|\n<a href="http://twitter.com/">more...</a>| if statuses.size > max
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                system 'notify-send', 'Termtter', text, '-t', '60000'
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
            end
         | 
| @@ -0,0 +1,21 @@ | |
| 1 | 
            +
            # -*- coding: utf-8 -*-
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Termtter::Client
         | 
| 4 | 
            +
              register_macro(:otsune, "update @%s 頭蓋骨の中身がお気の毒です.",
         | 
| 5 | 
            +
                :help => ['otsune {SCREENNAME}', 'update "@{SCREENNAME} 頭蓋骨の中身がお気の毒です"'],
         | 
| 6 | 
            +
                :completion_proc => lambda {|cmd, args|
         | 
| 7 | 
            +
                  find_user_candidates args, "#{cmd} %s"
         | 
| 8 | 
            +
                }
         | 
| 9 | 
            +
              )
         | 
| 10 | 
            +
            end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            module Termtter::Client
         | 
| 13 | 
            +
              register_macro(:otsnue, "update @%s 頭蓋骨の中身がお気の毒です.",
         | 
| 14 | 
            +
                :help => ['otsnue {SCREENNAME}', 'update @%s 頭が気の毒です.'],
         | 
| 15 | 
            +
                :completion_proc => lambda {|cmd, args|
         | 
| 16 | 
            +
                  find_user_candidates args, "#{cmd} %s"
         | 
| 17 | 
            +
                }
         | 
| 18 | 
            +
              )
         | 
| 19 | 
            +
            end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            # vim: fenc=utf8
         | 
| @@ -0,0 +1,35 @@ | |
| 1 | 
            +
            # -*- coding: utf-8 -*-
         | 
| 2 | 
            +
             | 
| 3 | 
            +
             | 
| 4 | 
            +
            module Termtter::Client
         | 
| 5 | 
            +
              configatron.plugins.outputz.set_default(:uri, 'termtter://twitter.com/status/update')
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              key = configatron.plugins.outputz.secret_key
         | 
| 8 | 
            +
              if key.instance_of? Configatron::Store
         | 
| 9 | 
            +
                puts 'Need your secret key'
         | 
| 10 | 
            +
                puts 'please set configatron.plugins.outputz.secret_key'
         | 
| 11 | 
            +
              else
         | 
| 12 | 
            +
                add_command /^(update|u)\s+(.*)/ do |m, t|
         | 
| 13 | 
            +
                  text = ERB.new(m[2]).result(binding).gsub(/\n/, ' ')
         | 
| 14 | 
            +
                  unless text.empty?
         | 
| 15 | 
            +
                    t.update_status(text)
         | 
| 16 | 
            +
                    puts "=> #{text}"
         | 
| 17 | 
            +
                  end
         | 
| 18 | 
            +
                  t.instance_variable_get('@connection').
         | 
| 19 | 
            +
                    start('outputz.com', 80) do |http|
         | 
| 20 | 
            +
                      key  = CGI.escape key
         | 
| 21 | 
            +
                      uri  = CGI.escape configatron.plugins.outputz.uri
         | 
| 22 | 
            +
                      size = text.split(//).size
         | 
| 23 | 
            +
                      http.post('/api/post', "key=#{key}&uri=#{uri}&size=#{size}")
         | 
| 24 | 
            +
                    end
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
              end
         | 
| 27 | 
            +
            end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
            # outputz.rb
         | 
| 30 | 
            +
            #   a plugin that report to outputz your post
         | 
| 31 | 
            +
            #
         | 
| 32 | 
            +
            # settings (note: must this order)
         | 
| 33 | 
            +
            #   configatron.plugins.outputz.secret_key = 'your secret key'
         | 
| 34 | 
            +
            #   plugin 'outputz'
         | 
| 35 | 
            +
             | 
    
        data/lib/plugin/pause.rb
    ADDED
    
    
| @@ -0,0 +1,53 @@ | |
| 1 | 
            +
            # -*- coding: utf-8 -*-
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Termtter::Client
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              public_storage[:plugins] = Dir["#{File.dirname(__FILE__)}/*.rb"].map do |f|
         | 
| 6 | 
            +
                f.match(%r|([^/]+).rb$|)[1]
         | 
| 7 | 
            +
              end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              register_command(
         | 
| 10 | 
            +
                :name      => :plugin, :aliases => [],
         | 
| 11 | 
            +
                :exec_proc => lambda {|arg|
         | 
| 12 | 
            +
                  begin
         | 
| 13 | 
            +
                    result = plugin arg.strip
         | 
| 14 | 
            +
                  rescue LoadError
         | 
| 15 | 
            +
                  ensure
         | 
| 16 | 
            +
                    puts "=> #{result.inspect}"
         | 
| 17 | 
            +
                  end
         | 
| 18 | 
            +
                },
         | 
| 19 | 
            +
                :completion_proc => lambda {|cmd, args|
         | 
| 20 | 
            +
                  find_user_candidates args, "#{cmd} %s"
         | 
| 21 | 
            +
                  unless args.empty?
         | 
| 22 | 
            +
                    find_plugin_candidates args, "#{cmd} %s"
         | 
| 23 | 
            +
                  else
         | 
| 24 | 
            +
                    public_storage[:plugins].sort
         | 
| 25 | 
            +
                  end
         | 
| 26 | 
            +
                },
         | 
| 27 | 
            +
                :help      => ['plugin FILE', 'Load a plugin']
         | 
| 28 | 
            +
              )
         | 
| 29 | 
            +
             | 
| 30 | 
            +
              register_command(
         | 
| 31 | 
            +
                :name      => :plugins, :aliases => [],
         | 
| 32 | 
            +
                :exec_proc => lambda {|arg|
         | 
| 33 | 
            +
                  puts public_storage[:plugins].sort.join("\n")
         | 
| 34 | 
            +
                },
         | 
| 35 | 
            +
                :help      => ['plugins', 'Show list of plugins']
         | 
| 36 | 
            +
              )
         | 
| 37 | 
            +
             | 
| 38 | 
            +
              def self.find_plugin_candidates(a, b)
         | 
| 39 | 
            +
                public_storage[:plugins].
         | 
| 40 | 
            +
                  grep(/^#{Regexp.quote a}/i).
         | 
| 41 | 
            +
                  map {|u| b % u }
         | 
| 42 | 
            +
              end
         | 
| 43 | 
            +
            end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
            # plugin.rb
         | 
| 46 | 
            +
            #   a dynamic plugin loader
         | 
| 47 | 
            +
            # example
         | 
| 48 | 
            +
            #   > u <%= not erbed %>
         | 
| 49 | 
            +
            #   => <%= not erbed %>
         | 
| 50 | 
            +
            #   > plugin erb
         | 
| 51 | 
            +
            #   => true
         | 
| 52 | 
            +
            #   > u <%= 1 + 2 %>
         | 
| 53 | 
            +
            #   => 3
         |