diff --git a/app/logical/artist_finder.rb b/app/logical/artist_finder.rb index 1853ce35f..4c72c2015 100644 --- a/app/logical/artist_finder.rb +++ b/app/logical/artist_finder.rb @@ -107,6 +107,8 @@ module ArtistFinder "ustream.tv/user", # http://www.ustream.tv/user/kazaputi "vk.com", # https://vk.com/id425850679 "weibo.com", # http://www.weibo.com/5536681649 + "weibo.com/u", + "weibo.com/p", "wp.com", "yande.re", "youtube.com", diff --git a/app/logical/sources/strategies.rb b/app/logical/sources/strategies.rb index 170b4849f..0e2f2f82c 100644 --- a/app/logical/sources/strategies.rb +++ b/app/logical/sources/strategies.rb @@ -12,7 +12,8 @@ module Sources Strategies::Nijie, Strategies::Pawoo, Strategies::Moebooru, - Strategies::HentaiFoundry + Strategies::HentaiFoundry, + Strategies::Weibo ] end diff --git a/app/logical/sources/strategies/weibo.rb b/app/logical/sources/strategies/weibo.rb new file mode 100644 index 000000000..84d5d8b75 --- /dev/null +++ b/app/logical/sources/strategies/weibo.rb @@ -0,0 +1,216 @@ +# Image URLS +# * http://ww1.sinaimg.cn/large/69917555gw1f6ggdghk28j20c87lbhdt.jpg +# +# Image Samples +# * http://ww4.sinaimg.cn/mw690/77a2d531gw1f4u411ws3aj20m816fagg.jpg +# * https://wx4.sinaimg.cn/orj360/e3930166gy1g546bz86cij20u00u040y.jpg +# * http://ww3.sinaimg.cn/mw1024/0065kjmOgw1fabcanrzx6j30f00lcjwv.jpg +# +# Page URLS +# * http://weibo.com/3357910224/EEHA1AyJP +# * https://www.weibo.com/5501756072/IF9fugHzj?from=page_1005055501756072_profile&wvr=6&mod=weibotime +# +# * http://photo.weibo.com/5732523783/talbum/detail/photo_id/4029784374069389?prel=p6_3 +# * http://photo.weibo.com/2125874520/wbphotos/large/mid/4194742441135220/pid/7eb64558gy1fnbryb5nzoj20dw10419t +# * http://tw.weibo.com/1300957955/3786333853668537 +# +# * https://m.weibo.cn/detail/4506950043618873 +# * https://m.weibo.cn/status/J33G4tH1B +# +# Video +# * https://www.weibo.com/5501756072/IF9fugHzj +# +# Profile URLS +# ### Short ID +# * https://www.weibo.com/5501756072 +# * https://www.weibo.com/u/5501756072 +# * https://m.weibo.cn/profile/5501756072 +# * https://m.weibo.cn/u/5501756072 +# ### Long ID +# * https://www.weibo.com/p/1005055501756072 + +module Sources + module Strategies + class Weibo < Base + PROFILE_URL_1 = %r{https?://(?:(?:www|m)\.)?weibo\.c(?:om|n)/(?:(?:u|profile)/)?(?\d+)\z}i + PROFILE_URL_2 = %r{https?://photo\.weibo\.com/(?\d+)}i + PROFILE_URL_3 = %r{https?://(?:www\.)?weibo\.com/p/(?\d+)}i + + PAGE_URL_1 = %r{https?://(?:www\.)?weibo\.com/(?\d+)/(?\w+)(?:\?.*)?\z}i + PAGE_URL_2 = %r{#{PROFILE_URL_2}/(?:wbphotos/large/mid|talbum/detail/photo_id)/(?\d+)(?:/pid/(?\w{32}))?}i + PAGE_URL_3 = %r{https?://m\.weibo\.cn/(detail/(?\d+)|status/(?\w+))}i + PAGE_URL_4 = %r{https?://tw\.weibo\.com/(?:(?\d+)|\w+)/(?\d+)}i + + IMAGE_URL = %r{https?://\w{3}\.sinaimg\.cn/\w+/(?\w{32})\.}i + + def domains + ["weibo.com", "weibo.cn", "weibocdn.com", "sinaimg.cn"] + end + + def site_name + "Weibo" + end + + def image_urls + urls = [] + + if url =~ IMAGE_URL + urls << self.class.convert_image_to_large(url) + elsif api_response.present? + if api_response["pics"].present? + urls += api_response["pics"].to_a.map { |pic| self.class.convert_image_to_large(pic["url"]) } + elsif api_response.dig("page_info", "type") == "video" + variants = api_response["page_info"]["media_info"].to_h.values + api_response["page_info"]["urls"].to_h.values + urls << variants.max_by do |variant| + if /template=(?\d+)x(?\d+)/ =~ variant.to_s + width.to_i * height.to_i + else + 0 + end + end + end + else + urls << url + end + + urls + end + + def image_url + image_id = url[PAGE_URL_2, :image_id] if url =~ PAGE_URL_2 + + if image_id.present? + image_urls.select { |i| i[IMAGE_URL, :image_id] == image_id }.compact.first + else + image_urls.first + end + end + + def preview_urls + image_urls.map { |img| img.gsub(%r{.cn/\w+/(\w+)}, '.cn/orj360/\1') } + end + + def page_url + if api_response.present? + artist_id = api_response["user"]["id"] + illust_id = api_response["bid"] + "https://www.weibo.com/#{artist_id}/#{illust_id}" + elsif url =~ IMAGE_URL + self.class.convert_image_to_large(url) + else + url + end + end + + def tags + return [] if api_response.blank? + + matches = api_response["text"]&.scan(/surl-text">#(.*?)#