Skip to content
Snippets Groups Projects
post.rb 4.1 KiB
Newer Older
Arnaud Levy's avatar
Arnaud Levy committed
# == Schema Information
#
# Table name: communication_website_imported_posts
#
Sébastien Gaya's avatar
Sébastien Gaya committed
#  id                 :uuid             not null, primary key
#  content            :text
#  data               :jsonb
#  excerpt            :text
#  identifier         :string
#  path               :text
#  published_at       :datetime
#  slug               :text
#  status             :integer          default(0)
#  title              :string
#  url                :text
#  created_at         :datetime         not null
#  updated_at         :datetime         not null
#  featured_medium_id :uuid
#  post_id            :uuid             not null
#  university_id      :uuid             not null
#  website_id         :uuid             not null
Arnaud Levy's avatar
Arnaud Levy committed
#
# Indexes
#
Sébastien Gaya's avatar
Sébastien Gaya committed
#  idx_communication_website_imported_posts_on_featured_medium_id  (featured_medium_id)
#  index_communication_website_imported_posts_on_post_id           (post_id)
#  index_communication_website_imported_posts_on_university_id     (university_id)
#  index_communication_website_imported_posts_on_website_id        (website_id)
Arnaud Levy's avatar
Arnaud Levy committed
#
# Foreign Keys
#
Sébastien Gaya's avatar
Sébastien Gaya committed
#  fk_rails_...  (featured_medium_id => communication_website_imported_media.id)
Arnaud Levy's avatar
Arnaud Levy committed
#  fk_rails_...  (post_id => communication_website_posts.id)
#  fk_rails_...  (university_id => universities.id)
#  fk_rails_...  (website_id => communication_website_imported_websites.id)
#
class Communication::Website::Imported::Post < ApplicationRecord
  belongs_to :university
  belongs_to :website,
             class_name: 'Communication::Website::Imported::Website'
  belongs_to :post,
             class_name: 'Communication::Website::Post',
             optional: true
Sébastien Gaya's avatar
Sébastien Gaya committed
  belongs_to :featured_medium,
             class_name: 'Communication::Website::Imported::Medium',
             optional: true
Arnaud Levy's avatar
Arnaud Levy committed

  before_validation :sync

Arnaud Levy's avatar
Arnaud Levy committed
  default_scope { order(path: :desc) }

Arnaud Levy's avatar
Arnaud Levy committed
  def data=(value)
    super value
    self.url = value['link']
    self.slug = value['slug']
    self.path = URI(self.url).path
    self.title = value['title']['rendered']
    self.excerpt = value['excerpt']['rendered']
    self.content = value['content']['rendered']
Arnaud Levy's avatar
Arnaud Levy committed
    self.created_at = value['date_gmt']
    self.updated_at = value['modified_gmt']
    self.published_at = value['date_gmt']
Sébastien Gaya's avatar
Sébastien Gaya committed
    self.featured_medium = website.media.find_by(identifier: value['featured_media']) unless value['featured_media'] == 0
Arnaud Levy's avatar
Arnaud Levy committed
  end

Arnaud Levy's avatar
Arnaud Levy committed
  def to_s
    "#{title}"
  end

  protected

  def sync
    if post.nil?
      self.post = Communication::Website::Post.new university: university,
                                                   website: website.website # Real website, not imported website
Arnaud Levy's avatar
Arnaud Levy committed
      self.post.title = "Untitled" # No title yet
Arnaud Levy's avatar
Arnaud Levy committed
      self.post.save
Sébastien Gaya's avatar
Sébastien Gaya committed
    else
      # Don't touch if there are local changes (this would destroy some nice work)
      # return if post.updated_at > updated_at
      # Don't touch if there are no remote changes (this would do useless server workload)
      # return if post.updated_at == updated_at
Arnaud Levy's avatar
Arnaud Levy committed
    end
Arnaud Levy's avatar
Arnaud Levy committed
    puts "Update post #{post.id}"
Sébastien Gaya's avatar
Sébastien Gaya committed
    sanitized_title = Wordpress.clean self.title.to_s
    post.title = sanitized_title unless sanitized_title.blank? # If there is no title, leave it with "Untitled"
Arnaud Levy's avatar
Arnaud Levy committed
    post.slug = slug
Arnaud Levy's avatar
Arnaud Levy committed
    post.description = ActionView::Base.full_sanitizer.sanitize excerpt.to_s
Arnaud Levy's avatar
Arnaud Levy committed
    post.text = Wordpress.clean content.to_s
Arnaud Levy's avatar
Arnaud Levy committed
    post.created_at = created_at
    post.updated_at = updated_at
Arnaud Levy's avatar
Arnaud Levy committed
    post.published_at = published_at if published_at
Arnaud Levy's avatar
Arnaud Levy committed
    post.published = true
Arnaud Levy's avatar
Arnaud Levy committed
    post.save
Arnaud Levy's avatar
Arnaud Levy committed
    download_first_image_as_featured_image if featured_medium.nil?
  end

  # Please refactor me i'm ugly
  def download_first_image_as_featured_image
    doc = Nokogiri::HTML(post.text.to_s)
    images = doc.css('img')
    if images.any?
      url = images.first.attr('src')
      uri = URI(url)
      filename = File.basename url
      http = Net::HTTP.new(uri.host, uri.port)
      http.use_ssl = true
      http.verify_mode = OpenSSL::SSL::VERIFY_NONE
      request = Net::HTTP::Get.new(uri.request_uri)
      response = http.request(request)
      begin
        post.featured_image.attach(io: StringIO.new(response.body), filename: filename, content_type: 'image/jpeg')
Arnaud Levy's avatar
Arnaud Levy committed
      rescue
Arnaud Levy's avatar
Arnaud Levy committed
      end
    end
Arnaud Levy's avatar
Arnaud Levy committed
  end
end