namespace :nico do desc 'ニコニコ DB 同期' task sync: :environment do require 'open3' require 'open-uri' require 'nokogiri' fetch_thumbnail = -> url { html = URI.open(url, read_timeout: 60, 'User-Agent' => 'Mozilla/5.0').read doc = Nokogiri::HTML(html) doc.at('meta[name="thumbnail"]')&.[]('content').presence } mysql_user = ENV['MYSQL_USER'] mysql_pass = ENV['MYSQL_PASS'] nizika_nico_path = ENV['NIZIKA_NICO_PATH'] stdout, stderr, status = Open3.capture3( { 'MYSQL_USER' => mysql_user, 'MYSQL_PASS' => mysql_pass }, 'python3', "#{ nizika_nico_path }/get_videos.py") if status.success? data = JSON.parse(stdout) data.each do |datum| post = Post.where('url LIKE ?', '%nicovideo.jp%').find { |post| post.url =~ %r{#{ Regexp.escape(datum['code']) }(?!\d)} } unless post title = datum['title'] url = "https://www.nicovideo.jp/watch/#{ datum['code'] }" thumbnail_base = fetch_thumbnail.(url) || '' rescue '' post = Post.new(title:, url:, thumbnail_base:, uploaded_user: nil) if thumbnail_base.present? post.thumbnail.attach( io: URI.open(thumbnail_base), filename: File.basename(URI.parse(thumbnail_base).path), content_type: 'image/jpeg') end post.save! post.resized_thumbnail! end current_tags = post.tags.where(category: 'nico').pluck(:name).sort new_tags = datum['tags'].map { |tag| "nico:#{ tag }" }.sort if current_tags != new_tags post.tags.destroy(post.tags.where(name: current_tags)) new_tags.each do |name| post.tags << Tag.find_or_initialize_by(name:, category: 'nico') end if post.tags.size < 20 name = 'タグ希望' post.tags.destroy(post.tags.find_by(name:)) post.tags << Tag.find_or_initialize_by(name:) { |tag| tag.category = 'meta' } end name = 'bot操作' post.tags.destroy(post.tags.find_by(name:)) post.tags << Tag.find_or_initialize_by(name:) { |tag| tag.category = 'meta' } end end end end end