Add author info to API endpoints

このコミットが含まれているのは:
Omar Roth 2018-09-04 21:35:25 -05:00
コミット bc49c7d181
1個のファイルの変更77行の追加29行の削除

ファイルの表示

@ -1412,7 +1412,11 @@ get "/feed/channel/:ucid" do |env|
document = XML.parse_html(json["content_html"].as_s) document = XML.parse_html(json["content_html"].as_s)
nodeset = document.xpath_nodes(%q(//li[contains(@class, "feed-item-container")])) nodeset = document.xpath_nodes(%q(//li[contains(@class, "feed-item-container")]))
videos = extract_videos(nodeset, ucid) if auto_generated
videos = extract_videos(nodeset)
else
videos = extract_videos(nodeset, ucid)
end
else else
videos = [] of SearchVideo videos = [] of SearchVideo
end end
@ -1440,13 +1444,18 @@ get "/feed/channel/:ucid" do |env|
xml.element("entry") do xml.element("entry") do
xml.element("id") { xml.text "yt:video:#{video.id}" } xml.element("id") { xml.text "yt:video:#{video.id}" }
xml.element("yt:videoId") { xml.text video.id } xml.element("yt:videoId") { xml.text video.id }
xml.element("yt:channelId") { xml.text ucid } xml.element("yt:channelId") { xml.text video.ucid }
xml.element("title") { xml.text video.title } xml.element("title") { xml.text video.title }
xml.element("link", rel: "alternate", href: "#{host_url}/watch?v=#{video.id}") xml.element("link", rel: "alternate", href: "#{host_url}/watch?v=#{video.id}")
xml.element("author") do xml.element("author") do
xml.element("name") { xml.text channel.author } if auto_generated
xml.element("uri") { xml.text "#{host_url}/channel/#{ucid}" } xml.element("name") { xml.text video.author }
xml.element("uri") { xml.text "#{host_url}/channel/#{video.ucid}" }
else
xml.element("name") { xml.text author }
xml.element("uri") { xml.text "#{host_url}/channel/#{ucid}" }
end
end end
xml.element("published") { xml.text video.published.to_s("%Y-%m-%dT%H:%M:%S%:z") } xml.element("published") { xml.text video.published.to_s("%Y-%m-%dT%H:%M:%S%:z") }
@ -1650,7 +1659,11 @@ get "/channel/:ucid" do |env|
document = XML.parse_html(json["content_html"].as_s) document = XML.parse_html(json["content_html"].as_s)
nodeset = document.xpath_nodes(%q(//li[contains(@class, "feed-item-container")])) nodeset = document.xpath_nodes(%q(//li[contains(@class, "feed-item-container")]))
videos = extract_videos(nodeset, ucid) if auto_generated
videos = extract_videos(nodeset)
else
videos = extract_videos(nodeset, ucid)
end
else else
videos = [] of SearchVideo videos = [] of SearchVideo
end end
@ -2296,7 +2309,11 @@ get "/api/v1/channels/:ucid" do |env|
document = XML.parse_html(json["content_html"].as_s) document = XML.parse_html(json["content_html"].as_s)
nodeset = document.xpath_nodes(%q(//li[contains(@class, "feed-item-container")])) nodeset = document.xpath_nodes(%q(//li[contains(@class, "feed-item-container")]))
videos = extract_videos(nodeset, ucid) if auto_generated
videos = extract_videos(nodeset)
else
videos = extract_videos(nodeset, ucid)
end
else else
videos = [] of SearchVideo videos = [] of SearchVideo
end end
@ -2390,6 +2407,16 @@ get "/api/v1/channels/:ucid" do |env|
json.field "title", video.title json.field "title", video.title
json.field "videoId", video.id json.field "videoId", video.id
if auto_generated
json.field "author", video.author
json.field "authorId", video.ucid
json.field "authorUrl", "/channel/#{video.ucid}"
else
json.field "author", author
json.field "authorId", ucid
json.field "authorUrl", "/channel/#{ucid}"
end
json.field "videoThumbnails" do json.field "videoThumbnails" do
generate_thumbnails(json, video.id) generate_thumbnails(json, video.id)
end end
@ -2417,6 +2444,7 @@ get "/api/v1/channels/:ucid/videos" do |env|
page ||= 1 page ||= 1
client = make_client(YT_URL) client = make_client(YT_URL)
if !ucid.match(/UC[a-zA-Z0-9_-]{22}/) if !ucid.match(/UC[a-zA-Z0-9_-]{22}/)
rss = client.get("/feeds/videos.xml?user=#{ucid}") rss = client.get("/feeds/videos.xml?user=#{ucid}")
rss = XML.parse_html(rss.body) rss = XML.parse_html(rss.body)
@ -2428,43 +2456,62 @@ get "/api/v1/channels/:ucid/videos" do |env|
end end
ucid = ucid.content ucid = ucid.content
url = "/api/v1/channels/#{ucid}/videos" author = rss.xpath_node("//author/name").not_nil!.content
if env.params.query next env.redirect "/feed/channel/#{ucid}"
url += "?#{env.params.query}" else
rss = client.get("/feeds/videos.xml?channel_id=#{ucid}")
rss = XML.parse_html(rss.body)
ucid = rss.xpath_node("//feed/channelid")
if !ucid
error_message = "User does not exist."
next templated "error"
end end
next env.redirect url
ucid = ucid.content
author = rss.xpath_node("//author/name").not_nil!.content
end end
url = produce_channel_videos_url(ucid, page) # Auto-generated channels
# https://support.google.com/youtube/answer/2579942
if author.ends_with? " - Topic"
auto_generated = true
end
url = produce_channel_videos_url(ucid, auto_generated: auto_generated)
response = client.get(url) response = client.get(url)
json = JSON.parse(response.body) json = JSON.parse(response.body)
if !json["content_html"]?
env.response.content_type = "application/json"
if response.status_code == 500 if json["content_html"]? && !json["content_html"].as_s.empty?
response = {"Error" => "Channel does not exist"}.to_json document = XML.parse_html(json["content_html"].as_s)
halt env, status_code: 404, response: response nodeset = document.xpath_nodes(%q(//li[contains(@class, "feed-item-container")]))
if auto_generated
videos = extract_videos(nodeset)
else else
next Array(String).new.to_json videos = extract_videos(nodeset, ucid)
end end
else
videos = [] of SearchVideo
end end
content_html = json["content_html"].as_s result = JSON.build do |json|
if content_html.empty?
env.response.content_type = "application/json"
next Hash(String, String).new.to_json
end
document = XML.parse_html(content_html)
videos = JSON.build do |json|
json.array do json.array do
nodeset = document.xpath_nodes(%q(//li[contains(@class, "feed-item-container")])) videos.each do |video|
extract_videos(nodeset, ucid).each do |video|
json.object do json.object do
json.field "title", video.title json.field "title", video.title
json.field "videoId", video.id json.field "videoId", video.id
if auto_generated
json.field "author", video.author
json.field "authorId", video.ucid
json.field "authorUrl", "/channel/#{video.ucid}"
else
json.field "author", author
json.field "authorId", ucid
json.field "authorUrl", "/channel/#{ucid}"
end
json.field "videoThumbnails" do json.field "videoThumbnails" do
generate_thumbnails(json, video.id) generate_thumbnails(json, video.id)
end end
@ -2481,7 +2528,7 @@ get "/api/v1/channels/:ucid/videos" do |env|
end end
env.response.content_type = "application/json" env.response.content_type = "application/json"
videos result
end end
get "/api/v1/search" do |env| get "/api/v1/search" do |env|
@ -2527,6 +2574,7 @@ get "/api/v1/search" do |env|
json.field "videoId", video.id json.field "videoId", video.id
json.field "author", video.author json.field "author", video.author
json.field "authorId", video.ucid
json.field "authorUrl", "/channel/#{video.ucid}" json.field "authorUrl", "/channel/#{video.ucid}"
json.field "videoThumbnails" do json.field "videoThumbnails" do