Skip to content

Instantly share code, notes, and snippets.

@Roman2K
Created March 3, 2009 16:41
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 Roman2K/73392 to your computer and use it in GitHub Desktop.
Save Roman2K/73392 to your computer and use it in GitHub Desktop.
# Minimalistic Mininova TV show browser with live search, written in Shoes.
#
# To run it, drop `minishoes.rb' onto `Shoes.app'. You should see something like
# the screen capture at:
# http://img4.imageshack.us/img4/106/minishows.png
#
require 'pathname'
require 'hpricot'
require 'open-uri'
class Show < Struct.new(:title, :episode_count, :path)
MININOVA = "http://www.mininova.org"
def initialize(link)
super \
link.inner_text,
link.parent.parent.search('td')[1].inner_html.to_i,
link.attributes['href']
end
def url
MININOVA + path
end
module Fetching
URL = MININOVA + '/cat/8'
CACHE = Pathname.new '/tmp/mininova-tv-shows'
def doc
CACHE.delete if CACHE.exist? && Time.now - CACHE.mtime > 5 * 60
if CACHE.exist?
Shoes.debug "loading %.1fKB" % (CACHE.size / 1024.0)
CACHE.open('r') { |f| Marshal.load f }
else
data = Hpricot(open(URL))
CACHE.open('w') { |f| Marshal.dump data, f }
Shoes.debug "cached %.1fKB" % (CACHE.size / 1024.0)
data
end
end
def shows
@shows ||=
doc.
search('tr td a[@href^=/sub]').
map { |link| Show.new link }.
reject { |show| show.title == "Other" }
end
end
module Display
def lay_out
flow do
background '#fff'..'#ccc'
flow :width => 0.2, :margin => 2 do
para "Search:"
end
flow :width => 0.6 do
@search = edit_line
@search.change do |field|
re = lambda { |source| Regexp.new(source, Regexp::IGNORECASE) }
matcher = re[field.text] rescue re[Regexp.escape(field.text)]
display_sorted shows.select { |s| matcher === s.title }
end
end
flow :width => 0.2, :margin => 2, :margin_right => gutter do
@count = para "", :align => 'right'
end
end
flow :height => 2 do
background '#aaa'
end
@list = flow
end
def display(collection)
@list.clear do
collection.each_with_index do |show, index|
flow do
background '#dadada' if index % 2 == 1
stack :width => 0.9 do
para link(show.title, :click => show.url)
end
stack :width => 0.1, :margin_right => gutter do
para show.episode_count, :align => 'right'
end
end
end
end
@count.text = collection.size
end
def display_sorted(collection)
display collection.sort_by { |show| -show.episode_count }
end
end
end
Shoes.app :width => 350 do
extend Show::Fetching
extend Show::Display
lay_out
display_sorted shows
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment