æããããã°ã©ã ãSinatraã§Webã¢ããªã«ããPart.12ï¼»CHAPTER9 ãããã£ããããã¯ã¼ã¯ã«ã¤ãªãããï¼½
è¨äºã®æ¦è¦
ãæããããã°ã©ã ãã®ï¼»CHAPTER9 ãããã£ããããã¯ã¼ã¯ã«ã¤ãªãããï¼½ãåèã«ãGoogleæ¤ç´¢ãå©ç¨ãã¦å¿çæã®æãçæãããã£ããããããä½æãã¾ãã
ç®æ¬¡
éçºç°å¢
- OSX 10.11.2 El Capitan
- ããã¹ãã¨ãã£ã¿ï¼ MacVim
- ã¿ã¼ããã«ã¨ãã¥ã¬ã¼ã¿ï¼ Macã¿ã¼ããã«
- ã·ã§ã«ï¼ zsh
- ããã±ã¼ã¸ããã¼ã¸ã£ï¼ Homebrew
- ãã©ã¦ã¶ï¼ Firefox - Ruby 2.0.0p645
- ãã¼ã¸ã§ã³ããã¼ã¸ã£ï¼ rbenv
- Webãã¬ã¼ã ã¯ã¼ã¯ï¼ Sinatra - MeCab 0.996
- æ¥æ¬èªè¾æ¸ï¼ IPAè¾æ¸
åèè¨äº
Rubyã®éçºç°å¢æ§ç¯ã¯ããã¡ãã®è¨äºãåèã«ããã¦ããã ãã¾ããã
ããã£ãã°ã°ã
å ¥åããä¼è©±ã®å 容ãGoogleã§æ¤ç´¢ããæ¤ç´¢çµæã®è¨äºããå¿çæãä½æãã¾ãã
ã¢ããªã±ã¼ã·ã§ã³ãã£ã¬ã¯ããªã®æ§æ
~/programinlove
|- proto.rb // CUIãã£ãããããã®ã¡ã¤ã³ãã¡ã¤ã«
|- unmo.rb // ãã£ããããããªãã¸ã§ã¯ãã®ã¢ãã«
|- responder.rb // å¿çãªãã¸ã§ã¯ãã®ã¢ãã«
|- dictionary.rb // è¾æ¸ãèªã¿è¾¼ã¿ç®¡çããã¯ã©ã¹
|- mecab_natto.rb // å½¢æ
ç´ è§£æå¨MeCabã使ãããã®ã¢ã¸ã¥ã¼ã«
|- morph.rb // MeCabNattoã¢ã¸ã¥ã¼ã«ãunmo.rbã§ä½¿ãããã®ã¢ã¸ã¥ã¼ã«
|- morkov.rb // ãã«ã³ãé£éãå©ç¨ãã¦è¾æ¸ãä½æããã¯ã©ã¹
|- gugulu.rb // Googleæ¤ç´¢ãå©ç¨ããããã®ã¯ã©ã¹
|- utils.rb // select_randomã¡ã½ããããå®ç¾©ããã ãã®ãã¡ã¤ã«
|- log.txt // ã¦ã¼ã¶ã®å
¥åå±¥æ´ãä¿åãããã°ãã¡ã¤ã«
|- /dics // è¾æ¸ãã¡ã¤ã«ãæ ¼ç´ãããã£ã¬ã¯ããª
| |- random.txt // ã©ã³ãã ãªå¿çãè¿ãããã®è¾æ¸
| |- pattern.txt // ãã¿ã¼ã³ã«åã£ãå¿çãè¿ãããã®è¾æ¸
| |- template.txt // ãã³ãã¬ã¼ãã使ã£ãå¿çãè¿ãããã®è¾æ¸
| |- markov.dat // ãã«ã³ãé£éã使ã£ãå¿çãè¿ãããã®è¾æ¸
|- noby.rb // Webã¢ããªã®ã¡ã¤ã³ãã¡ã¤ã«
|- /views // ãã¥ã¼ã®ãã³ãã¬ã¼ããé
ç½®ãããã£ã¬ã¯ããª
| |- index.erb // ãã£ããã®ã¤ã³ã¿ã¼ãã§ã¼ã¹ã表示ãããã¥ã¼
|- /public // éçãã¡ã¤ã«ãé
ç½®ãããã£ã¬ã¯ããª
|- nobycanvas.js // ãã£ã©ã¯ã¿ã¼ã®ç»åãã¢ãã¡ã¼ã·ã§ã³ãããJavascript
|- styles.css // ãã£ããã®ã¤ã³ã¿ã¼ãã§ã¼ã¹ãã¬ã¤ã¢ã¦ãããcss
|- /img // ç»åãã¡ã¤ã«ãæ ¼ç´ãããã£ã¬ã¯ããª
|- /normal // 平常æã®ç»åãæ ¼ç´ãããã£ã¬ã¯ããª
|- /blink // ç¬ãã®ç»åãæ ¼ç´ãããã£ã¬ã¯ããª
|- /lookaround // å¨å²ãè¦åãç»åãæ ¼ç´ãããã£ã¬ã¯ããª
|- /talk // åãç»åãæ ¼ç´ãããã£ã¬ã¯ããª
~ 以ä¸ã«è¡¨æ
ãã¨ã®ç»åãæ ¼ç´ãããã£ã¬ã¯ããªãé
ç½®
ã½ã¼ã¹ã³ã¼ã
gugulu.rb
ã§ã¯ãXML/HTML parserã®Oga
ã使ã£ã¦HTMLãåãåºããæ¤ç´¢çµæã®URLãåå¾ãã¦ãã¾ãã
æ¸ç±å
ã«è¨è¼ããã¦ããã¨ãããç¾å¨ã¯Google Web APIãå©ç¨ã§ããªããããªã®ã§ãå°éã«ã¹ã¯ã¬ã¤ãã³ã°ãã¾ããã
ã¾ãããµã³ãã«ããã°ã©ã ã¨ç°ãªããGugulu
ã¯ã©ã¹ã®search
ã¡ã½ããã®æ»ãå¤ããæ¤ç´¢çµæã®ãªã³ã¯ã®ã¿ã¤ãã«ã¨URLãæ ¼ç´ããé
åã«å¤æ´ãããããresponder.rb
ã®GuguluResponder
ã¯ã©ã¹ãæ»ãå¤ã«åããã¦å¤æ´ãã¾ããã
ãã®ä»ã®Rubyãã¡ã¤ã«ã¯ããµã³ãã«ããã°ã©ã ã¨åæ§ã®è¨è¿°ã§ãç¹ã«å¤æ´ã¯ããã¾ããã
gugulu.rb
require 'open-uri' # URLãéã require 'Oga' # HTMLãXMLããã¼ã¹ãã require 'cgi' # æ¥æ¬èªãURLã¨ã³ã³ã¼ã require_relative 'morph' class Gugulu GOOGLE = "https://www.google.co.jp" def search(query) # æ¤ç´¢æååãURLã¨ã³ã³ã¼ããã¦åå¾ search_word = CGI.escape(query) # æ¤ç´¢çµæã®URLãéãã¦è¦ç´ ãåå¾ query_url = "#{GOOGLE}/search?q=#{search_word}" begin search_result = open(query_url) do |f| # æååã対çã«utf-8ãæå®ãã¦htmlãèªã¿è¾¼ã f.read.encode('utf-8') end get_elements(search_result) rescue => e # Googleæ¤ç´¢ãã§ããªãã£ãå ´åã¯ã¨ã©ã¼ã表示 puts("Search Error: #{e.message}") end end def get_elements(html) element = [] # HTMLããã¼ã¹ãã¦ãªã³ã¯ã¨ã¿ã¤ãã«ãåå¾ doc = Oga.parse_html(html) doc.xpath('//h3/a').each do |node| link = node.get('href') # open-uriã§httpãéããã¨ããã¨ã¨ã©ã¼ãåºãã®ã§ # httpsã®urlã®ã¿åå¾ãã if link =~ /^\/url\?q=https:/ element.push({ title: node.text, url: "#{GOOGLE}#{link}" }) end end # æ¤ç´¢çµæã®ãªã³ã¯ãéãããç¢ºèª element.each do |elem| begin open(elem[:url]) rescue => e # ãªã³ã¯ãéããªãå ´åã¯é åããåé¤ element.delete(elem) end end end def self::get_sentences(url) html = open(url){|f| f.read} return html2sentences(html) end def self::html2sentences(html) html.gsub!(/<!--.*?-->/im, '') html.gsub!(/<.*?>/im, '') html = CGI.unescapeHTML(html) html.gsub!(/ /, ' ') html.gsub!(/^[\sã]+/, '') html.gsub!(/[\sã]+$/, '') html.gsub!(/(([ã?ï¼!ï¼](?![\r\n]))+)/, "\\1\n") sentences = [] html.split(/\n/).each do |line| parts = Morph::analyze(line) next unless Morph::sentence?(parts) sentences.push(line) end return sentences end end if $0 == __FILE__ Morph::init_analyzer ggl = Gugulu.new loop do print('Search: ') line = gets.chomp break if line.empty? begin elements = ggl.search(line) elements.each.with_index(1) do |elem, i| puts('%d %s'%[i, elem[:title]]) puts(' ' + elem[:url]) end puts loop do print('Get: ') line = gets.chomp break if line.empty? no = line.to_i - 1 next unless elements[no] puts(Gugulu::get_sentences(elements[no][:url])) end rescue => e puts("error: " + e.message) end end end
responder.rb/GuguluResponder
class GuguluResponder < Responder def initialize(name, dictionary) @ggl = Gugulu.new @query_opts = '' super end def response(input, parts, mood) keywords = [] parts.each{|w, p| keywords.push(w) if Morph::keyword?(p)} query = (keywords.empty?) ? input : keywords.join(' ') query += ' ' + @query_opts begin result = @ggl.search(query) raise('no results') if result.empty? elem = select_random(result) sentences = Gugulu::get_sentences(elem[:url]) markov = Markov.new sentences.each do |line| parts = Morph::analyze(line) markov.add_sentence(parts) @dictionary.study(line, parts) end resp = markov.generate(select_random(keywords)) return resp unless resp.nil? rescue => e puts(e.message) end return select_random(@dictionary.random) end end
ãã®ã³ã¼ãã®ã³ãããã«ã¯ã[chapter9-3]ã®ã¿ã°ãä»ãã¦ã¾ãã
å®è¡çµæ
ã¿ã¼ããã«ã§noby.rb
ãåããããã©ã¦ã¶ã«http://localhost:4567
ãå
¥åãã¾ãã
~/programinlove
$ruby noby.rb
å ´åã«ãã£ã¦ã¯ãèµ·ä¼ã®çããä¼è©±ã楽ããã¾ãã
åèæ¸ç±
åèè¨äº
Sinatraã«ã¤ãã¦ã¯ããã¡ãã®è¨äºãåèã«ããã¦ããã ãã¾ããã
- Rubyの入門や書き捨てアプリを作る場合は sinatraがオススメ! - むかぁ~ どっと こむ
- SinatraとjQueryでおよそ100行で作るAjax掲示板アプリケーション - gaaamiiのブログ
- Sinatra: README (Japanese)
é¢é£è¨äº
- æããããã°ã©ã ãSinatraã§Webã¢ããªã«ããPart.0ï¼»ã¯ããã«ï¼½
- æããããã°ã©ã ãSinatraã§Webã¢ããªã«ããPart.1ï¼»CHAPTER3 ã»ãã¨ã«ç¡è½ï¼½
- æããããã°ã©ã ãSinatraã§Webã¢ããªã«ããPart.2ï¼»CHAPTER4 ããããã®GUIï¼½â
- æããããã°ã©ã ãSinatraã§Webã¢ããªã«ããPart.3ï¼»CHAPTER4 ããããã®GUIï¼½â¡
- æããããã°ã©ã ãSinatraã§Webã¢ããªã«ããPart.4ï¼»CHAPTER4 ããããã®GUIï¼½â¢
- æããããã°ã©ã ãSinatraã§Webã¢ããªã«ããPart.5ï¼»CHAPTER5 è¾æ¸ãçæã«ï¼½
- æããããã°ã©ã ãSinatraã§Webã¢ããªã«ããPart.6ï¼»CHAPTER6 ææ
ã³ã³ããã¼ã«ã®éè¡å¸«ï¼½â
- æããããã°ã©ã ãSinatraã§Webã¢ããªã«ããPart.7ï¼»CHAPTER6 ææ
ã³ã³ããã¼ã«ã®éè¡å¸«ï¼½â¡
- æããããã°ã©ã ãSinatraã§Webã¢ããªã«ããPart.8ï¼»CHAPTER7 å¦ç¿ã®ã¹ã¹ã¡ï¼½â
- æããããã°ã©ã ãSinatraã§Webã¢ããªã«ããPart.9ï¼»CHAPTER7 å¦ç¿ã®ã¹ã¹ã¡ï¼½â¡
- æããããã°ã©ã ãSinatraã§Webã¢ããªã«ããPart.10ï¼»CHAPTER7 å¦ç¿ã®ã¹ã¹ã¡ï¼½â¢
- æããããã°ã©ã ãSinatraã§Webã¢ããªã«ããPart.11ï¼»CHAPTER8 æç« ãä½ãåºãï¼½
- æããããã°ã©ã ãSinatraã§Webã¢ããªã«ããPart.13ï¼»ãããã«ï¼½