Permalink
Browse files

Initial import

  • Loading branch information...
0 parents commit ac644b902cf15e506eedb4230b9eb16bd6374480 @oz committed Feb 27, 2012
Showing with 163 additions and 0 deletions.
  1. +2 −0 .gitignore
  2. +14 −0 LICENSE
  3. +8 −0 Makefile
  4. +23 −0 README.md
  5. +24 −0 package.json
  6. +92 −0 tw.coffee
@@ -0,0 +1,2 @@
+node_modules/
+tw.js
14 LICENSE
@@ -0,0 +1,14 @@
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
+ Version 2, December 2004
+
+Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
+
+Everyone is permitted to copy and distribute verbatim or modified
+copies of this license document, and changing it is allowed as long
+as the name is changed.
+
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. You just DO WHAT THE FUCK YOU WANT TO.
+
@@ -0,0 +1,8 @@
+all: clean
+ echo '#!/usr/bin/env node' >> tw.js
+ coffee -p tw.coffee >> tw.js
+
+clean:
+ rm -rf ./tw.js
+
+PHONY: all
@@ -0,0 +1,23 @@
+tw
+==
+
+tw is a tiny node script that I often use to avoid switching to a
+browser when a Twitter status link is mentioned. It was written a long
+time ago, is ugly, but does the job.
+
+What does it do?
+
+ $ tw -h
+ Usage: tw <tweet url | tweet id>
+ -h show help
+ -u <nick> user's tweets
+ -s <search term> search tweets
+ -i <status id | status url> show status
+
+Really, that's it.
+
+ $ tw 'https://twitter.com/#!/CodeWisdom/status/170178134015094784'
+ CodeWisdom (16/1/2012 16:10:3 UTC): "Larry Wall is right. Laziness should be a
+ virtue. So that's why I prefer automation." - Brendan Eich (creator of
+ JavaScript)
+
@@ -0,0 +1,24 @@
+{
+ "author": "Arnaud Berthomier <oz@cyprio.net>",
+ "name": "tw",
+ "description": "Twitter helper",
+ "keywords": ["twitter", "client"],
+ "version": "0.1.0",
+ "repository": {
+ "type": "git",
+ "url": "http://github.com/oz/tw.git"
+ },
+ "engines": {
+ "node": "~0.6"
+ },
+ "bin" : {
+ "tw": "./tw.js"
+ },
+ "dependencies": {
+ "optimist": "~0.3"
+ },
+ "devDependencies": {
+ "coffee-script": "~1.2"
+ },
+ "optionalDependencies": {}
+}
@@ -0,0 +1,92 @@
+#!/usr/bin/env coffee
+
+argv = require('optimist').argv
+http = require 'http'
+URL = require 'url'
+PROG_NAME = 'tw'
+
+if argv.h
+ console.log "Usage: "+PROG_NAME+" <tweet url | tweet id>"
+ console.log " -h show help"
+ console.log " -u <nick> user's tweets"
+ console.log " -s <search term> search tweets"
+ console.log " -i <status id | status url> show status\n"
+ process.exit()
+
+##
+# Fetch JSON from Twitter API, and call cb with the parsed JSON object
+# unless Twitter sends us an error...
+#
+# @param [String] path API Path or complete URL
+# @param [Function] cb Callback receiving Twitter's response as an Object
+fetch = (path, cb) ->
+ show_error = (obj) -> console.log "Error: " + (obj.message || obj.error)
+ if path.match(/^http/) && url = URL.parse(path)
+ options =
+ host: url.hostname
+ post: (url.protocol == 'https' ? 443 : 80)
+ path: url.pathname + url.search
+ else
+ options =
+ host: "api.twitter.com"
+ post: 443
+ path: path
+
+ req = http.get options, (res) ->
+ res.setEncoding "utf8"
+ buf = ""
+ res.on "data", (chunk) -> buf += chunk
+ res.on "end", () ->
+ o = JSON.parse buf
+ if o.error
+ console.log "Error: " + o.error
+ else
+ cb o
+ req.on "error", (e) -> show_error e
+
+##
+# Fetch a user's statuses
+# @param [String] screen_name User's screen name
+viewUserStatuses = (screen_name) ->
+ path = "/1/statuses/user_timeline.json?screen_name=" + screen_name
+ fetch path, (tweets) -> tweets.map (e) -> displayTweet e
+
+##
+# Fetch one status by ID
+# @param [String] status_id A status ID
+viewStatus = (status_id) ->
+ path = "/1/statuses/show/" + status_id + ".json"
+ fetch path, (tweet) -> displayTweet tweet
+
+##
+# Search tweets
+# @param [String] query Search query
+searchTweets = (query) ->
+ uri = 'https://search.twitter.com/search.json?q='+query
+ fetch uri, (response) ->
+ response.results ||= []
+ response.results.map (r) ->
+ displayTweet
+ created_at: r.created_at,
+ user:
+ screen_name: r.from_user,
+ text: r.text
+
+##
+# Display a single tweet
+# @param [Object] tweet A tweet object fresh from Twitter's API
+displayTweet = (tweet) ->
+ d = new Date tweet.created_at
+ date = ['Date' , 'Month' , 'FullYear'].map (n) -> d['getUTC'+n]()
+ time = ['Hours', 'Minutes', 'Seconds' ].map (n) -> d['getUTC'+n]()
+ date_str = date.join('/') + ' ' + time.join(':') + ' UTC'
+ console.log tweet.user.screen_name + " (" + date_str + "): " + tweet.text + "\n"
+
+##
+# Args dispatching's done here.
+viewUserStatuses argv.u if argv.u
+searchTweets argv.s if argv.s
+viewStatus argv.i if argv.i
+# Handle <tw 123123123> and/or <tw "http://..../status/123123213">
+if argv._.length == 1 && matches = (""+argv._[0]).match(/(status\/)?(\d+)\/?/)
+ viewStatus matches[2]

0 comments on commit ac644b9

Please sign in to comment.