Created
March 3, 2009 16:41
-
-
Save Roman2K/73392 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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