mirror of
https://gitea.invidious.io/iv-org/invidious-copy-2022-08-14.git
synced 2024-08-15 00:53:20 +00:00
139786b9ef
Don't use the whole Hash everywhere. Also fall back nicely to english string if no translation exists.
263 lines
7.3 KiB
Crystal
263 lines
7.3 KiB
Crystal
struct SearchVideo
|
|
include DB::Serializable
|
|
|
|
property title : String
|
|
property id : String
|
|
property author : String
|
|
property ucid : String
|
|
property published : Time
|
|
property views : Int64
|
|
property description_html : String
|
|
property length_seconds : Int32
|
|
property live_now : Bool
|
|
property premium : Bool
|
|
property premiere_timestamp : Time?
|
|
|
|
def to_xml(auto_generated, query_params, xml : XML::Builder)
|
|
query_params["v"] = self.id
|
|
|
|
xml.element("entry") do
|
|
xml.element("id") { xml.text "yt:video:#{self.id}" }
|
|
xml.element("yt:videoId") { xml.text self.id }
|
|
xml.element("yt:channelId") { xml.text self.ucid }
|
|
xml.element("title") { xml.text self.title }
|
|
xml.element("link", rel: "alternate", href: "#{HOST_URL}/watch?#{query_params}")
|
|
|
|
xml.element("author") do
|
|
if auto_generated
|
|
xml.element("name") { xml.text self.author }
|
|
xml.element("uri") { xml.text "#{HOST_URL}/channel/#{self.ucid}" }
|
|
else
|
|
xml.element("name") { xml.text author }
|
|
xml.element("uri") { xml.text "#{HOST_URL}/channel/#{ucid}" }
|
|
end
|
|
end
|
|
|
|
xml.element("content", type: "xhtml") do
|
|
xml.element("div", xmlns: "http://www.w3.org/1999/xhtml") do
|
|
xml.element("a", href: "#{HOST_URL}/watch?#{query_params}") do
|
|
xml.element("img", src: "#{HOST_URL}/vi/#{self.id}/mqdefault.jpg")
|
|
end
|
|
|
|
xml.element("p", style: "word-break:break-word;white-space:pre-wrap") { xml.text html_to_content(self.description_html) }
|
|
end
|
|
end
|
|
|
|
xml.element("published") { xml.text self.published.to_s("%Y-%m-%dT%H:%M:%S%:z") }
|
|
|
|
xml.element("media:group") do
|
|
xml.element("media:title") { xml.text self.title }
|
|
xml.element("media:thumbnail", url: "#{HOST_URL}/vi/#{self.id}/mqdefault.jpg",
|
|
width: "320", height: "180")
|
|
xml.element("media:description") { xml.text html_to_content(self.description_html) }
|
|
end
|
|
|
|
xml.element("media:community") do
|
|
xml.element("media:statistics", views: self.views)
|
|
end
|
|
end
|
|
end
|
|
|
|
def to_xml(auto_generated, query_params, _xml : Nil)
|
|
XML.build do |xml|
|
|
to_xml(auto_generated, query_params, xml)
|
|
end
|
|
end
|
|
|
|
def to_json(locale : String?, json : JSON::Builder)
|
|
json.object do
|
|
json.field "type", "video"
|
|
json.field "title", self.title
|
|
json.field "videoId", self.id
|
|
|
|
json.field "author", self.author
|
|
json.field "authorId", self.ucid
|
|
json.field "authorUrl", "/channel/#{self.ucid}"
|
|
|
|
json.field "videoThumbnails" do
|
|
generate_thumbnails(json, self.id)
|
|
end
|
|
|
|
json.field "description", html_to_content(self.description_html)
|
|
json.field "descriptionHtml", self.description_html
|
|
|
|
json.field "viewCount", self.views
|
|
json.field "published", self.published.to_unix
|
|
json.field "publishedText", translate(locale, "`x` ago", recode_date(self.published, locale))
|
|
json.field "lengthSeconds", self.length_seconds
|
|
json.field "liveNow", self.live_now
|
|
json.field "premium", self.premium
|
|
json.field "isUpcoming", self.is_upcoming
|
|
|
|
if self.premiere_timestamp
|
|
json.field "premiereTimestamp", self.premiere_timestamp.try &.to_unix
|
|
end
|
|
end
|
|
end
|
|
|
|
# TODO: remove the locale and follow the crystal convention
|
|
def to_json(locale : String?, _json : Nil)
|
|
JSON.build do |json|
|
|
to_json(locale, json)
|
|
end
|
|
end
|
|
|
|
def to_json(json : JSON::Builder)
|
|
to_json(nil, json)
|
|
end
|
|
|
|
def is_upcoming
|
|
premiere_timestamp ? true : false
|
|
end
|
|
end
|
|
|
|
struct SearchPlaylistVideo
|
|
include DB::Serializable
|
|
|
|
property title : String
|
|
property id : String
|
|
property length_seconds : Int32
|
|
end
|
|
|
|
struct SearchPlaylist
|
|
include DB::Serializable
|
|
|
|
property title : String
|
|
property id : String
|
|
property author : String
|
|
property ucid : String
|
|
property video_count : Int32
|
|
property videos : Array(SearchPlaylistVideo)
|
|
property thumbnail : String?
|
|
|
|
def to_json(locale : String?, json : JSON::Builder)
|
|
json.object do
|
|
json.field "type", "playlist"
|
|
json.field "title", self.title
|
|
json.field "playlistId", self.id
|
|
json.field "playlistThumbnail", self.thumbnail
|
|
|
|
json.field "author", self.author
|
|
json.field "authorId", self.ucid
|
|
json.field "authorUrl", "/channel/#{self.ucid}"
|
|
|
|
json.field "videoCount", self.video_count
|
|
json.field "videos" do
|
|
json.array do
|
|
self.videos.each do |video|
|
|
json.object do
|
|
json.field "title", video.title
|
|
json.field "videoId", video.id
|
|
json.field "lengthSeconds", video.length_seconds
|
|
|
|
json.field "videoThumbnails" do
|
|
generate_thumbnails(json, video.id)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
# TODO: remove the locale and follow the crystal convention
|
|
def to_json(locale : String?, _json : Nil)
|
|
JSON.build do |json|
|
|
to_json(locale, json)
|
|
end
|
|
end
|
|
|
|
def to_json(json : JSON::Builder)
|
|
to_json(nil, json)
|
|
end
|
|
end
|
|
|
|
struct SearchChannel
|
|
include DB::Serializable
|
|
|
|
property author : String
|
|
property ucid : String
|
|
property author_thumbnail : String
|
|
property subscriber_count : Int32
|
|
property video_count : Int32
|
|
property description_html : String
|
|
property auto_generated : Bool
|
|
|
|
def to_json(locale : String?, json : JSON::Builder)
|
|
json.object do
|
|
json.field "type", "channel"
|
|
json.field "author", self.author
|
|
json.field "authorId", self.ucid
|
|
json.field "authorUrl", "/channel/#{self.ucid}"
|
|
|
|
json.field "authorThumbnails" do
|
|
json.array do
|
|
qualities = {32, 48, 76, 100, 176, 512}
|
|
|
|
qualities.each do |quality|
|
|
json.object do
|
|
json.field "url", self.author_thumbnail.gsub(/=\d+/, "=s#{quality}")
|
|
json.field "width", quality
|
|
json.field "height", quality
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
json.field "autoGenerated", self.auto_generated
|
|
json.field "subCount", self.subscriber_count
|
|
json.field "videoCount", self.video_count
|
|
|
|
json.field "description", html_to_content(self.description_html)
|
|
json.field "descriptionHtml", self.description_html
|
|
end
|
|
end
|
|
|
|
# TODO: remove the locale and follow the crystal convention
|
|
def to_json(locale : String?, _json : Nil)
|
|
JSON.build do |json|
|
|
to_json(locale, json)
|
|
end
|
|
end
|
|
|
|
def to_json(json : JSON::Builder)
|
|
to_json(nil, json)
|
|
end
|
|
end
|
|
|
|
class Category
|
|
include DB::Serializable
|
|
|
|
property title : String
|
|
property contents : Array(SearchItem) | Array(Video)
|
|
property url : String?
|
|
property description_html : String
|
|
property badges : Array(Tuple(String, String))?
|
|
|
|
def to_json(locale : String?, json : JSON::Builder)
|
|
json.object do
|
|
json.field "type", "category"
|
|
json.field "title", self.title
|
|
json.field "contents" do
|
|
json.array do
|
|
self.contents.each do |item|
|
|
item.to_json(locale, json)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
# TODO: remove the locale and follow the crystal convention
|
|
def to_json(locale : String?, _json : Nil)
|
|
JSON.build do |json|
|
|
to_json(locale, json)
|
|
end
|
|
end
|
|
|
|
def to_json(json : JSON::Builder)
|
|
to_json(nil, json)
|
|
end
|
|
end
|
|
|
|
alias SearchItem = SearchVideo | SearchChannel | SearchPlaylist | Category
|