Skip to content

Instantly share code, notes, and snippets.

@nobu
Created July 2, 2009 10:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nobu/139408 to your computer and use it in GitHub Desktop.
Save nobu/139408 to your computer and use it in GitHub Desktop.
gisto.rb
#!/usr/bin/ruby
require 'optparse'
require 'net/http'
require 'time'
require 'cgi'
class Gist
GIST = URI.parse('http://gist.github.com/')
POST = GIST + 'gists'
DELETE = GIST + 'delete'
MINE = GIST + 'mine'
def read(id)
Net::HTTP.get(GIST + "#{id}.txt")
end
def post(data)
Net::HTTP.post_form(POST, data)
end
def delete(id)
Net::HTTP.get(DELETE + id.to_s)
end
include Enumerable
def each(user = nil, &block)
page = user ? GIST + user : MINE.dup
page.query = auth.map {|k, v| "#{k}=#{v}"}.join('&')
begin
data = Net::HTTP.get(page)
data.scan(/<span><a \s+href="\/(\d+)">.*?<\/span>
\s*<span>([^<>]+)?<\/span>.*?
<abbr \s+class="relatize"[^<>]*>([^<>]+)
.*?id="LC1">(.*?)<\/div>/mx) do |name, desc, time, lc1|
time = Time.parse(time).localtime
lc1 = CGI.unescapeHTML(lc1.gsub(/<[^<>]*>/, '')).gsub(/&nbsp;/, ' ')
yield name, time, desc, lc1
end
end while page = data[/<a href="\/([^<>\"]*?)"[^<>]+>Older/, 1] and
page = GIST + CGI.unescapeHTML(page)
end
def self.github_config(name)
`git config --global github.#{name}`.chomp
end
def self.get_auth
if (user = github_config('user')).empty?
{}
else
{:login => user, :token => github_config('token')}
end
end
@@auth = nil
def auth
@@auth ||= self.class.get_auth
end
def data(name, ext, content, private_gist)
data = {
'file_name[gistfile1]' => name,
'file_ext[gistfile1]' => ext,
'file_contents[gistfile1]' => content,
}
data['private'] = 'on' if private_gist
data.update(auth)
end
def write(content, name = nil, private_gist = @private_gist)
ext = File.extname(name) if name
req = post(data(name, ext, content, private_gist))
req['Location']
end
def paste(file)
content = (file == '-' ? (file = nil; STDIN.read) : File.read(file))
write(content, file)
end
alias copy read
def show(name)
data = copy(name)
if STDOUT.tty? and pager = ENV["PAGER"]
pager = pager.dup
begin
IO.popen(pager, "w") {|pg| pg.puts(data)}
return
rescue SystemCallError
end
end
data
end
def list(user = nil)
each(user) do |name, time, desc, line|
printf "%-10s %s %s%s\n", name, time.strftime("%Y-%m-%d %H:%M:%S %z"), (desc ? '=' : ' '), (desc||line)
end
nil
end
def delete(name)
end
attr_reader :mode
def mode=(new)
raise "mode given twice" if @mode
@mode = new
end
def parse_options(opt, argv)
@private_gist = false
@mode = nil
opt.on("-p", "--private", "post private") do
self.mode = :paste
@private_gist = true
end
opt.on("-c", "--cat", "--copy", "copy data") do self.mode = :copy end
opt.on("-s", "--show", "show data") do self.mode = :show end
opt.on("-l", "--list", "list data") do self.mode = :list end
!opt.parse!(argv).empty? or @mode == :list
end
def do(args)
mode = self.mode || :paste
if args.empty?
if result = __send__(mode)
puts result
end
else
args.each do |name|
if result = __send__(mode, name)
puts result
end
end
end
end
end
gist = Gist.new
ARGV.options do |opt|
gist.parse_options(opt, ARGV) or abort(opt.to_s)
end
gist.do(ARGV)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment