Skip to content
This repository
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 329 lines (293 sloc) 9.792 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328
require 'rubygems'
gem 'main', '>= 2.8.2'
gem 'highline', '>= 1.4.0'
gem 'activerecord', '>= 2.1'
gem 'sqlite3-ruby', '>= 1.2.2'
require 'main'
require 'highline/import'
require 'activerecord'
require 'sqlite3'

HighLine.track_eof = false
CLI_ROOT = File.expand_path(File.join(File.dirname(__FILE__), 'cli'))
require CLI_ROOT + '/config'
require CLI_ROOT + '/helpers'
Dir[CLI_ROOT + '/models/*.rb'].each { |m| require m }

include Twitter::CLI::Helpers

Main {
  def run
    puts "twitter [command] --help for usage instructions."
    puts "The available commands are: \n install, uninstall, add, remove, list, change, post, befriend, defriend, follow, leave, d and timeline."
  end
  
  mode 'install' do
    description 'Creates the sqlite3 database and runs the migrations.'
    def run
      migrate
      attempt_import
      say 'Twitter installed.'
    end
  end
  
  mode 'uninstall' do
    description 'Removes the sqlite3 database. There is no undo for this.'
    def run
      FileUtils.rm(Twitter::CLI::Config[:database]) if File.exists?(Twitter::CLI::Config[:database])
      say 'Twitter gem uninstalled.'
    end
  end
  
  mode 'add' do
    description 'Adds a new twitter account to the database. Prompts for username and password.'
    argument('username', 'u') {
      optional
      description 'optional username'
    }
    argument('password', 'p') {
      optional
      description 'optional password'
    }
    
    def run
      account = Hash.new
      say "Add New Account:"
      
      # allows optional username arg
      if params['username'].given?
        account[:username] = params['username'].value
      else
        account[:username] = ask('Username: ') do |q|
          q.validate = /\S+/
        end
      end
      
      # allows optional password arg
      if params['password'].given?
        account[:password] = params['password'].value
      else
        account[:password] = ask("Password (won't be displayed): ") do |q|
          q.echo = false
          q.validate = /\S+/
        end
      end
      
      do_work do
        base(account[:username], account[:password]).verify_credentials
        Account.add(account)
        say 'Account added.'
      end
    end
  end
  
  mode 'remove' do
    description 'Removes a twitter account from the database. If username provided it removes that username else it prompts with list and asks for which one you would like to remove.'
    argument( 'username' ) {
      optional
      description 'username of account you would like to remove'
    }
    
    def run
      do_work do
        if params['username'].given?
          account = Account.find_by_username(params['username'].value)
        else
          Account.find(:all, :order => 'username').each do |a|
            say "#{a.id}. #{a}"
          end
          account_id = ask 'Account to remove (enter number): ' do |q|
            q.validate = /\d+/
          end
        end
        
        begin
          account = account_id ? Account.find(account_id) : account
          account_name = account.username
          account.destroy
          Account.set_current(Account.first) if Account.new_active_needed?
          say "#{account_name} has been removed.\n"
        rescue ActiveRecord::RecordNotFound
          say "ERROR: Account could not be found. Try again. \n"
        end
      end
    end
  end
  
  mode 'list' do
    description 'Lists all the accounts that have been added and puts a * by the current one that is used for posting, etc.'
    def run
      do_work do
        if Account.count == 0
          say 'No accounts have been added.'
        else
          say 'Account List'
          Account.find(:all, :order => 'username').each do |a|
            say a
          end
        end
      end
    end
  end
  
  mode 'change' do
    description 'Changes the current account being used for posting etc. to the username provided. If no username is provided, a list is presented and you can choose the account from there.'
    argument( 'username' ) {
      optional
      description 'username of account you would like to switched to'
    }
    
    def run
      do_work do
        if params['username'].given?
          new_current = Account.find_by_username(params['username'].value)
        else
          Account.find(:all, :order => 'username').each do |a|
            say "#{a.id}. #{a}"
          end
          new_current = ask 'Change current account to (enter number): ' do |q|
            q.validate = /\d+/
          end
        end
        
        begin
          current = Account.set_current(new_current)
          say "#{current} is now the current account.\n"
        rescue ActiveRecord::RecordNotFound
          say "ERROR: Account could not be found. Try again. \n"
        end
      end
    end
  end
  
  mode 'post' do
    description "Posts a message to twitter using the current account. The following are all valid examples from the command line:
$ twitter post 'my update'
$ twitter post my update with quotes
$ echo 'my update from stdin' | twitter post"
    def run
      do_work do
        post = ARGV.size > 1 ? ARGV.join(" ") : ARGV.shift
        say "Sending twitter update"
        finished, status = false, nil
        progress_thread = Thread.new { until finished; print "."; $stdout.flush; sleep 0.5; end; }
        post_thread = Thread.new(binding()) do |b|
          status = base.post(post, :source => Twitter::SourceName)
          finished = true
        end
        post_thread.join
        progress_thread.join
        say "Got it! New twitter created at: #{status.created_at}\n"
      end
    end
  end

  mode 'befriend' do
    description "Allows you to add a user as a friend"
    argument('username') {
      required
      description 'username or id of twitterrer to befriend'
    }

    def run
      do_work do
        username = params['username'].value
        base.create_friendship(username)
        say "#{username} has been added as a friend. follow notifications with 'twitter follow #{username}'"
      end
    end
  end

  mode 'defriend' do
    description "Allows you to remove a user from being a friend"
    argument('username') {
      required
      description 'username or id of twitterrer to defriend'
    }

    def run
      do_work do
        username = params['username'].value
        base.destroy_friendship(username)
        say "#{username} has been removed from your friends"
      end
    end
  end
  
  mode 'follow' do
    description "Allows you to turn on notifications for a user"
    argument('username') {
      required
      description 'username or id of twitterrer to follow'
    }
    
    def run
      do_work do
        username = params['username'].value
        base.follow(username)
        say "You are now following notifications from #{username}"
      end
    end
  end
  
  mode 'leave' do
    description "Allows you to turn off notifications for a user"
    argument('username') {
      required
      description 'username or id of twitterrer to leave'
    }
    
    def run
      do_work do
        username = params['username'].value
        base.leave(username)
        say "You are no longer following notifications from #{username}"
      end
    end
  end
  
  mode 'd' do
    description "Allows you to direct message a user. The following are all valid examples from the command line:
$ twitter d jnunemaker 'yo homeboy'
$ twitter d jnunemaker yo homeboy
$ echo 'yo homeboy' | twitter d jnunemaker"
    argument('username') {
      required
      description 'username or id of twitterrer to direct message'
    }
    
    def run
      do_work do
        username = params['username'].value
        post = ARGV.size > 1 ? ARGV.join(" ") : ARGV.shift
        base.d(username, post)
        say "Direct message sent to #{username}"
      end
    end
  end
  
  mode 'timeline' do
    description "Allows you to view your timeline, your friends or the public one"
    argument( 'timeline' ) {
      description 'the timeline you wish to see (friends, public, me)'
      default 'friends'
    }
    option('force', 'f') {
      description "Ignore since_id and show first page of results even if there aren't new ones"
    }
    
    def run
      do_work do
        timeline = params['timeline'].value == 'me' ? 'user' : params['timeline'].value
        options, since_id = {}, Configuration["#{timeline}_since_id"]
        options[:since_id] = since_id if !since_id.blank? && !params['force'].given?
        cache = [:friends, :user].include?(timeline)
        collection = base.timeline(timeline.to_sym, options)
        output_tweets(collection, {:cache => cache, :since_prefix => timeline})
      end
    end
  end
  
  mode 'replies' do
    description 'Allows you to view all @replies at you'
    option('force', 'f') {
      description "Ignore since_id and show first page of replies even if there aren't new ones"
    }
    
    def run
      do_work do
        options, since_id = {}, Configuration["replies_since_id"]
        options[:since_id] = since_id if !since_id.blank? && !params['force'].given?
        collection = base.replies(options)
        output_tweets(collection, {:since_prefix => 'replies'})
      end
    end
  end
  
  mode 'clear_config' do
    def run
      do_work do
        count = Configuration.count
        Configuration.destroy_all
        say("#{count} configuration entries cleared.")
      end
    end
  end
  
  mode 'open' do
    description 'Opens the given twitter user in a browser window'
    argument('username') {
      required
      description "username or id of twitterrer who's page you would like to see"
    }
    
    def run
      `open http://twitter.com/#{params['username'].value}`
    end
  end
}
Something went wrong with that request. Please try again.