Skip to content

Instantly share code, notes, and snippets.

@felinebabies
Last active July 11, 2019 09:48
Show Gist options
  • Save felinebabies/25a02a82c5f7d34b53c3 to your computer and use it in GitHub Desktop.
Save felinebabies/25a02a82c5f7d34b53c3 to your computer and use it in GitHub Desktop.
Raspberry pi にインストールしたAquesTalkPiに、YAHOO!トピックスを読み上げさせるスクリプト
# coding: utf-8
# YAHOO!トピックスの見出し一覧を取得し、差分を読み上げる
require 'nokogiri'
require 'open-uri'
require 'yaml'
require 'optparse'
#当スクリプトファイルの所在
$scriptdir = File.expand_path(File.dirname(__FILE__))
#前回分トピック保存用ファイルパス
$recenttopicsfile = $scriptdir + "/recenttopics.yml"
#AquesTalkPiとaplayコマンドのフルパス
$aquestalkpath = "/home/pi/aquestalkpi/AquesTalkPi"
$aplaypath = "/usr/bin/aplay"
#トピック取得先URL
targeturl = "https://news.yahoo.co.jp/topics"
#カテゴリ用プレフィックス
$categoryprefix = "カテゴリ、◇"
# コマンドラインオプション解析
def cmdline
args = {}
OptionParser.new do |parser|
parser.on('-a', '--all', '全トピックを読み上げる') {|v| args[:all] = v}
parser.parse!(ARGV)
end
return args
end
#ファイルからトピック取得結果を読み込む
def loadFileTopics(topicfilepath)
recenttopics = []
if File.exist?(topicfilepath) then
File.open(topicfilepath, "r") do |f|
f.flock(File::LOCK_SH)
recenttopics = YAML.load(f.read)
end
end
return recenttopics
end
#最新のトピック取得結果を読み込む
def getTopics(targeturl)
categories = []
charset = nil
html = open(targeturl) do |f|
charset = f.charset
f.read
end
doc = Nokogiri::HTML.parse(html, nil, charset)
topicxpath = "//div[contains(concat(\" \",normalize-space(@class),\" \"), \" list \")]/ul/li[not (contains(@class, 'ft'))]/a"
category = {
"name" => "",
"topics" => []
}
doc.xpath(topicxpath).each do |node|
parentli = node.ancestors("li").first
if parentli.attribute("class") && parentli.attribute("class").value == "ttl" then
if(category["name"].empty?) then
category["name"] = $categoryprefix + node.text
else
categories << category
category = {
"name" => $categoryprefix + node.text,
"topics" => []
}
end
else
category["topics"] << node.text
end
#末尾のnew,写真、動画を削除
category["topics"].collect! do |topic|
topic.gsub!(/(new$)/, "")
topic.gsub!(/(動画$)/, "")
topic.gsub(/(写真$)/, "")
end
end
categories << category
return categories
end
#指定した配列内のトピックを読み上げる
def readoutString(str)
`#{$aquestalkpath} "#{str}" | #{$aplaypath}`
end
#指定した配列内のトピックを読み上げる
def readoutTopics(topics)
topics.each do |topic|
readoutString(topic)
sleep(1)
end
end
#データをファイルに保存する
def saveTopics(topicfilepath, topics)
File.open(topicfilepath, File::RDWR|File::CREAT) do |yml|
yml.flock(File::LOCK_EX)
yml.rewind
YAML.dump(topics, yml)
yml.flush
yml.truncate(yml.pos)
end
end
#トピックの差分を得る
def getDiffTopics(oldtopics, newtopics)
difftopics = []
newtopics.each_with_index do |newcategory, idx|
if ! oldtopics[idx] then
difftopics << newcategory
next
end
oldcategory = oldtopics[idx]
diffcategory = newcategory.clone
diffcategory["topics"] = newcategory["topics"] - oldcategory["topics"]
difftopics << diffcategory
end
return difftopics
end
# コマンドライン解析
args = cmdline
#処理開始
recenttopics = loadFileTopics($recenttopicsfile)
topics = getTopics(targeturl)
if(args[:all]) then
newtopics = topics
else
#差分を得る
newtopics = getDiffTopics(recenttopics, topics)
end
#新着があれば読み上げを実行する
newtopics.each do |category|
if category["topics"].empty? then
next
end
readoutString(category["name"])
sleep(1)
readoutTopics(category["topics"])
end
#今回のトピックスをファイルに書き込む
saveTopics($recenttopicsfile, topics)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment