Last active
July 11, 2019 09:48
-
-
Save felinebabies/25a02a82c5f7d34b53c3 to your computer and use it in GitHub Desktop.
Raspberry pi にインストールしたAquesTalkPiに、YAHOO!トピックスを読み上げさせるスクリプト
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
# 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