Skip to content

Instantly share code, notes, and snippets.

@melborne
Created July 11, 2011 07:28
Show Gist options
  • Save melborne/1075425 to your computer and use it in GitHub Desktop.
Save melborne/1075425 to your computer and use it in GitHub Desktop.
GyaoRank
# encoding: UTF-8
require_relative 'system_extensions'
requires :'open-uri', :rss, :date
set :cache, Dalli::Client.new(ENV['MEMCACHE_SERVERS'],
:username => ENV['MEMCACHE_USERNAME'],
:password => ENV['MEMCACHE_PASSWORD'],
:expires_in => 1.day)
configure do
APP_TITLE = "Gyao Rankings"
end
get '/' do
redirect '/daily/music'
end
get '/:term/:category' do |term, category|
@term, @category, @date = term, category, Date.today
@videos = videos(term, category, @date.to_s)
@urls = %w(daily weekly newly).product %w(music movie drama anime owarai variety all)
haml :index
end
get '/style.css' do
scss :style
end
helpers do
def videos(*term_category_date)
key = term_category_date * '/'
if vdata = settings.cache.get(key)
vdata
else
vdata = get_videos(*term_category_date)
settings.cache.set(key, vdata)
vdata
end
rescue
get_videos(*term_category_date)
end
def get_videos(*term_category_date)
ranking = rank_data(term_category_date.first 2)
video_data(ranking)
end
def rank_data(*term_category)
rss = open( URL(:rank) + term_category*'/' ) { |f| RSS::Parser.parse f.read }
rss.items.inject([]) { |mem, item| mem << item.title.scan(/[^「」]+/) }
end
def video_data(ranking)
ranking.thread_with(true) do |artist, title|
opts = ["vq=" + URI.encode("%s %s" % [artist, title]), "format=5"]*'&'
entry = Nokogiri::XML(open [URL(:video), opts]*'?').search('entry').first
data = { artist: artist, title: title }
if entry
q = { url: entry.xpath('media:group/media:content').first['url'],
type: entry.xpath('media:group/media:content').first['type'],
count: entry.xpath('yt:statistics').first['viewCount'] }
data.update q
end
data
end
end
def URL(code)
{ video: 'http://gdata.youtube.com/feeds/api/videos',
rank: 'http://gyao.yahoo.co.jp/rss/ranking/c/' }[code]
end
end
require 'bundler'
Bundler.require
$LOAD_PATH << File.expand_path(File.dirname(__FILE__))
require 'app'
run Sinatra::Application
source :rubygems
gem 'sinatra'
gem 'haml'
gem 'sass'
gem 'dalli'
gem 'nokogiri'
#category
%span= "%s %s" % [@category.capitalize, @term]
%span#date= " as of #@date"
#video
[email protected]_with_index do |d, i|
.ranking
.label
%span.rank= i+1
%span.title= "%s - %s" % [d[:artist], d[:title]]
- if d[:url]
%object{:width => '303', :height => '250'}
%param{:name => 'movie', :value => d[:url]}
%embed{:src => d[:url], :type => d[:type], :width => '303',:height => '250'}
.play_count
%span= "%s played" % d[:count]
- else
.not_found NOT FOUND
!!! 5
%html
%head
%meta{:charset => 'utf-8'}
%title= APP_TITLE
%link{:rel => 'stylesheet', :href => '/style.css'}
%body
%body
%header
#title GyaoRank
#menu
%form{:name => 'menu'}
%select{:name => 'Ranking', :onChange => "document.location.href='/'+document.menu.Ranking.options[document.menu.Ranking.selectedIndex].value"}
[email protected] do |url|
-if url == [@term,@category]
%option{:selected => 'selected'}= url*'/'
-else
%option= url*'/'
#main
= yield
%footer
%a#blog{:href => "http://d.hatena.ne.jp/keyesberry"} hp12c
* {
margin: 0;
padding: 0;
font-family: Trebuchet ms, Verdana, Myriad Web, Syntax, sans-serif
}
@mixin rounded($topl:4px, $topr:4px, $bottomr:4px, $bottoml:4px) {
border-radius: $topl $topr $bottomr $bottoml;
-moz-border-radius: $topl $topr $bottomr $bottoml;
}
body {
background-color: #212121;
width: 1000px;
margin: 20px auto;
}
header {
display:block;
height: 50px;
#title {
font-size: 1.8em;
float: left;
color: orange;
}
#menu {
float: left;
margin: 7px 20px;
}
}
#category {
clear: left;
font-size: 1.6em;
color: yellow;
background-color: green;
padding: 5px 15px;
@include rounded();
#date {
font-size: 0.8em;
color: orange;
}
}
.ranking {
font-size: 0.8em;
color: gray;
font-weight: bold;
width: 330px;
height: 350px;
float: left;
}
#video {
margin-top: 20px;
}
.label {
height: 60px;
font-size: 1.5em;
.rank {
@include rounded(14px,14px,14px,14px);
background-color: orange;
color: red;
padding: 5px;
}
.title {
color: lightgray;
font-size: 0.9em;
}
}
.not_found {
height: 140px;
width: 302px;
background-color: gray;
color: #ffffff;
text-align: center;
font-weight: bold;
font-size: 240%;
padding-top: 90px;
}
.play_count {
font-size: 0.9em;
color: yellow;
text-align: right;
width: 303px;
}
footer {
clear: both;
margin-top: 20px;
text-align: center;
@include rounded();
#blog {
text-decoration: none;
color: yellow;
}
}
# encoding: UTF-8
module Enumerable
def thread_with(order=false)
mem = []
map.with_index do |*item, i|
Thread.new(*item) do |*_item|
mem << [i, yield(*_item)]
end
end.each(&:join)
(order ? mem.sort : mem).map(&:last)
end
end
class Fixnum
def day
self*60*60*24
end
alias days day
end
module Kernel
def requires(*features)
features.each { |f| require f.to_s }
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment