c4se記:さっちゃんですよ☆

.。oO(さっちゃんですよヾ(〃l _ l)ノ゙☆)

.。oO(此のblogは、主に音樂考察Programming に分類されますよ。ヾ(〃l _ l)ノ゙♬♪♡)

音樂は SoundCloud に公開中です。

考察は現在は主に Scrapbox で公表中です。

Programming は GitHub で開發中です。

歌詞検索serviceから検索して歌詞を採ってくる

Rubyで。歌詞検索serviceから検索して歌詞を採ってくる。
解説はしない。

#!ruby
# encoding=utf-8
require 'open-uri'
require 'nokogiri'
require 'choice'

class LyricsPage
  # param [String] uri
  def initialize uri
    @uri = URI::escape uri
    @is_fetched = false
  end

  # Define properties with lazy loading.
  [:title, :artist, :lyrics].each do |name|
    define_method name do
      val_name = :"@#{name.to_s}"
      fetch if instance_variable_get(val_name) == nil
      instance_variable_get val_name
    end
    define_method :"#{name.to_s}=" do |val|
      instance_variable_set :"@#{name.to_s}", val
    end
  end

  # return [String]
  def to_s
    <<"LYRICS"
title: #{title}
artist: #{artist}
lyrics:#{lyrics}
LYRICS
  end

private
  def fetch
    return if @is_fetched
    html = Nokogiri::HTML open(@uri).read
    @title = html.css('#status-heading h1').text
    @artist = html.css('table.lyric-data td')[0].text
    @lyrics = html.css('#lyric-trunk').text
    @is_fetched = true
  end
end

# param [String] text
# retuen [Array] LyricsPage[]
def search_lyrics text
  base_uri = 'http://www.kget.jp'
  html = Nokogiri::HTML open("#{base_uri}/search/index.php?c=0&t=#{URI::escape text}&v=&f=").read
  html.css('ul.songlist li').map do |li|
    page = LyricsPage.new base_uri + li.css('a.lyric-anchor')[0]['href']
    page.title = li.css('h2.title').text
    page.artist = li.css('p.artist a').text
    page
  end
end

Choice.options do
  option :out do
    short '-o'
    long '--out=FILE'
    desc 'Output file.'
    filter{|val| open(val, 'w') }
    default STDOUT
  end

  option :help do
    long '--help'
  end
end

STDOUT.sync = true
out = Choice[:out]
pages = search_lyrics ARGV[ARGV.length - 1].encode('utf-8')
if pages.length == 0
  out.puts 'Not found'
elsif pages.length == 1
  out.puts pages[0]
else
  puts pages.zip(1..pages.length).inject(''){|acum, page|
    i = page[1]
    page = page[0]
    acum + <<"PAGE"
#{i}:\t#{page.title} #{page.artist}
PAGE
  }
  print "1..#{pages.length}? "
  out.puts pages[STDIN.gets.to_i - 1]
end
# vim:set et sw=2 sts=2 ff=unix: