class Jekyll::MediumCrossPostGenerator

Public Instance Methods

crosspost_payload(crossposted, post, content, title, url, published_at) click to toggle source
# File lib/jekyll-crosspost-to-medium.rb, line 127
def crosspost_payload(crossposted, post, content, title, url, published_at)
  # Update any absolute URLs
  # But don’t clobber protocol-less (i.e. "//") URLs
  content = content.gsub /href=(["'])\/(?!\/)/, "href=\\1#{@site.config['url']}/"
  content = content.gsub /src=(["'])\/(?!\/)/, "src=\\1#{@site.config['url']}/"
  # puts content

  # Save canonical URL
  canonical_url = url

  # Prepend the title and add a link back to originating site
  content.prepend("<h1>#{title}</h1>")
  # Append a canonical link and text
  # TODO Accept a position option, e.g., top, bottom.
  #
  # Use the user's config if it exists
  if @settings['text']
      canonical_text = "#{@settings['text']}"
      canonical_text = canonical_text.gsub /{{ url }}/, canonical_url
  # Otherwise, use boilerplate
  else
      canonical_text = "<p><i>This article was originally posted <a href=\"#{url}\" rel=\"canonical\">on my own site</a>.</i></p>"
  end
  content << canonical_text

  # Strip domain name from the URL we check against
  url = url.sub(/^#{@site.config['url']}?/,'')

  # coerce tage to an array
  tags = post.data['tags']
  if tags.kind_of? String
    tags = tags.split(',')
  end

  # Only cross-post if content has not already been cross-posted
  if url and ! crossposted.has_key? url
    payload = {
      'title'         => title,
      'contentFormat' => "html",
      'content'       => content,
      'tags'          => tags,
      'publishStatus' => @settings['status'] || "public",
      'publishedAt'   => published_at.iso8601,
      'license'       => @settings['license'] || "all-rights-reserved",
      'canonicalUrl'  => canonical_url
    }

    if medium_url = crosspost_to_medium(payload)
      crossposted[url] = medium_url
      # Update cache
      File.open(@crossposted_file, 'w') { |f| YAML.dump(crossposted, f) }
    end
  end
end
crosspost_to_medium(payload) click to toggle source
# File lib/jekyll-crosspost-to-medium.rb, line 183
def crosspost_to_medium(payload)
  user_id = ENV['MEDIUM_USER_ID'] or false
  token = ENV['MEDIUM_INTEGRATION_TOKEN'] or false
  medium_api = URI.parse("https://api.medium.com/v1/users/#{user_id}/posts")

  # Build the connection
  https = Net::HTTP.new(medium_api.host, medium_api.port)
  https.use_ssl = true
  request = Net::HTTP::Post.new(medium_api.path)

  # Set the headers
  request['Authorization'] = "Bearer #{token}"
  request['Content-Type'] = "application/json"
  request['Accept'] = "application/json"
  request['Accept-Charset'] = "utf-8"

  # Set the payload
  request.body = JSON.generate(payload)

  # Post it
  response = https.request(request)

  if response.code == '201'
    medium_response = JSON.parse(response.body)
    puts "Posted '#{payload['title']}' to Medium as #{payload['publishStatus']} (#{medium_response['data']['url']})"
    return medium_response['data']['url']
  else
    puts "Attempted to post '#{payload['title']}' to Medium. They responded #{response.body}"
    return false
  end
end
generate(site) click to toggle source
# File lib/jekyll-crosspost-to-medium.rb, line 29
def generate(site)
  @site = site

  @settings = @site.config['jekyll-crosspost_to_medium'] || {}
  globally_enabled = if @settings.has_key? 'enabled' then @settings['enabled'] else true end
  cache_dir = @settings['cache'] || @site.config['source'] + '/.jekyll-crosspost_to_medium'
  backdate = if @settings.has_key? 'backdate' then @settings['backdate'] else true end
  @crossposted_file = File.join(cache_dir, "medium_crossposted.yml")

  if globally_enabled
    # puts "Cross-posting enabled"
    user_id = ENV['MEDIUM_USER_ID'] or false
    token = ENV['MEDIUM_INTEGRATION_TOKEN'] or false

    if ! user_id or ! token
      raise ArgumentError, "MediumCrossPostGenerator: Environment variables not found"
      return
    end

    if defined?(cache_dir)
      FileUtils.mkdir_p(cache_dir)

      if File.exists?(@crossposted_file)
        crossposted = open(@crossposted_file) { |f| YAML.load(f) }
        # convert from an array to a hash (upgrading older versions of this plugin)
        if crossposted.kind_of?(Array)
          new_crossposted = {}
          crossposted.each do |url|
            new_crossposted[url] = 'unknown'
          end
          crossposted = new_crossposted
        end
        # end upgrade
      else
        crossposted = {}
      end

      # If Jekyll 3.0, use hooks
      if (Jekyll.const_defined? :Hooks)
        Jekyll::Hooks.register :posts, :post_render do |post|
          if ! post.published?
            next
          end

          crosspost = post.data.include? 'crosspost_to_medium'
          if ! crosspost or ! post.data['crosspost_to_medium']
            next
          end

          content = post.content
          url = "#{@site.config['url']}#{post.url}"
          title = post.data['title']
          
          published_at = backdate ? post.date : DateTime.now

          crosspost_payload(crossposted, post, content, title, url, published_at)
        end
      else
        
        # post Jekyll commit 0c0aea3
        # https://github.com/jekyll/jekyll/commit/0c0aea3ad7d2605325d420a23d21729c5cf7cf88
        if defined? site.find_converter_instance
          markdown_converter = @site.find_converter_instance(Jekyll::Converters::Markdown)
        # Prior to Jekyll commit 0c0aea3
        else
          markdown_converter = @site.getConverterImpl(Jekyll::Converters::Markdown)
        end

        @site.posts.each do |post|

          if ! post.published?
            next
          end

          crosspost = post.data.include? 'crosspost_to_medium'
          if ! crosspost or ! post.data['crosspost_to_medium']
            next
          end

          # Convert the content
          content = markdown_converter.convert(post.content)
          # Render any plugins
          content = (Liquid::Template.parse content).render @site.site_payload

          url = "#{@site.config['url']}#{post.url}"
          title = post.title
          
          published_at = backdate ? post.date : DateTime.now

          crosspost_payload(crossposted, post, content, title, url, published_at)
          
        end
      end
    end
  end
end