Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ source "https://rubygems.org"
# Specify your gem's dependencies in medium_to_webflow.gemspec
gemspec

gem "webflow-rb", git: "https://github.com/pjpires/webflow-rb.git", ref: "e04902b"

group :development do
gem "debug"
gem "rake", "~> 13.0"
Expand Down
11 changes: 10 additions & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
GIT
remote: https://github.com/pjpires/webflow-rb.git
revision: e04902b84ea39dda09aeac70704e7817bef0c7cb
ref: e04902b
specs:
webflow-rb (1.1.3)

PATH
remote: .
specs:
medium_to_webflow (0.1.0)
medium_to_webflow (0.2.0.beta1)
httparty (~> 0.22.0)
nokogiri (~> 1.17)
rss (~> 0.3.1)
thor (~> 1.3)
webflow-rb (~> 1.1)

GEM
remote: https://rubygems.org/
Expand Down Expand Up @@ -103,6 +111,7 @@ DEPENDENCIES
rubocop (~> 1.21)
rubocop-rake (~> 0.6.0)
rubocop-rspec (~> 3.2.0)
webflow-rb!

BUNDLED WITH
2.5.23
2 changes: 1 addition & 1 deletion lib/medium_to_webflow.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

require_relative "medium_to_webflow/medium/client"
require_relative "medium_to_webflow/medium/post"
require_relative "medium_to_webflow/webflow/client"
require_relative "medium_to_webflow/webflow/adapter"
require_relative "medium_to_webflow/sync_service"
require_relative "medium_to_webflow/cli"

Expand Down
68 changes: 55 additions & 13 deletions lib/medium_to_webflow/sync_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ def self.call(**args)

def initialize(medium_username:, webflow_api_token:, webflow_collection_id:, field_mappings:)
@medium_username = medium_username
@webflow_api_token = webflow_api_token
@webflow_collection_id = webflow_collection_id
@webflow_adapter = Webflow::Adapter.new(webflow_api_token, webflow_collection_id)
@field_mappings = field_mappings
@logger = MediumToWebflow.configuration.logger
end
Expand All @@ -21,7 +20,7 @@ def call
medium_posts = fetch_medium_posts
@logger.info "Found #{medium_posts.count} posts to sync"

sync_to_webflow(medium_posts)
sync_medium_posts_to_webflow(medium_posts)

@logger.info "Sync completed successfully!"
rescue StandardError => e
Expand All @@ -36,18 +35,61 @@ def fetch_medium_posts
Medium::Client.new(username: @medium_username).fetch_posts
end

def sync_to_webflow(posts)
webflow_client = Webflow::Client.new(
api_token: @webflow_api_token,
collection_id: @webflow_collection_id,
field_mappings: @field_mappings
)
def sync_medium_posts_to_webflow(medium_posts)
medium_posts.each_with_index do |medium_post, index|
@logger.debug "Processing post: #{medium_post.title}"
sync_medium_post_to_webflow(medium_post)
@logger.info "Successfully synced: #{medium_post.title} (#{index + 1}/#{medium_posts.count})"
end
end

def sync_medium_post_to_webflow(medium_post)
fields = build_webflow_fields(medium_post)
medium_slug_field_name = @field_mappings.key("slug")
existing_item = find_webflow_item_by_slug(medium_post.send(medium_slug_field_name))

if existing_item
handle_existing_webflow_item(existing_item, fields, medium_post)
else
create_webflow_item(fields)
end
end

def find_webflow_item_by_slug(slug)
@webflow_adapter.find_by_slug(slug)
end

def handle_existing_webflow_item(existing_item, fields, medium_post)
if MediumToWebflow.configuration.force_update
@logger.debug "Forcing update of existing item: #{existing_item[:id]}"
@webflow_adapter.update_item(existing_item[:id], fields)
else
@logger.info "Skipping existing item: #{medium_post.title} (use --force-update to override)"
end
end

def create_webflow_item(fields)
@webflow_adapter.create_item(fields)
end

def build_webflow_fields(medium_post)
@field_mappings.each_with_object({}) do |(medium_field_name, webflow_field_name), fields|
value = medium_post.public_send(medium_field_name)
next if value.nil?

posts.each_with_index do |post, index|
@logger.debug "Processing post: #{post.title}"
webflow_client.upsert_post(post)
@logger.info "Successfully synced: #{post.title} (#{index + 1}/#{posts.count})"
fields[webflow_field_name] = process_field_value(medium_field_name, value)
end
end

def process_field_value(medium_field_name, value)
# Handle the image field by converting it to Webflow's expected format { url: "image_url" }
return { url: value } if medium_field_name == :image_url

# Convert DateTime/Time objects to ISO8601 format for Webflow's date fields
return value.iso8601 if value.respond_to?(:iso8601)

# Return value as-is for all other field types
value
end
end
end
2 changes: 1 addition & 1 deletion lib/medium_to_webflow/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module MediumToWebflow
VERSION = "0.1.0"
VERSION = "0.2.0.beta1"
end
48 changes: 48 additions & 0 deletions lib/medium_to_webflow/webflow/adapter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# frozen_string_literal: true

require "webflow"

module MediumToWebflow
module Webflow
class Adapter
def initialize(api_token, collection_id)
@client = ::Webflow::Client.new(api_token)
@collection_id = collection_id
@logger = MediumToWebflow.configuration.logger
end

def find_by_slug(slug)
@client.list_items(@collection_id, query_params: { slug: slug }).first
rescue ::Webflow::Error => e
handle_error("list_items", e)
nil
end

def create_item(fields)
@logger.debug "Creating Webflow item in collection: #{@collection_id}"
@logger.debug "Fields: #{fields.inspect}" if MediumToWebflow.configuration.verbose

@client.create_item(@collection_id, fields, is_draft: true)
rescue ::Webflow::Error => e
handle_error("create_item", e)
end

def update_item(item_id, fields)
@logger.debug "Updating Webflow item: #{item_id} in collection: #{@collection_id}"
@logger.debug "Fields: #{fields.inspect}" if MediumToWebflow.configuration.verbose

@client.update_item(@collection_id, item_id, fields, is_draft: true)
rescue ::Webflow::Error => e
handle_error("update_item", e)
end

private

def handle_error(operation, error)
error_message = "Webflow #{operation} operation failed: #{error.message}"
@logger.error error_message
raise MediumToWebflow::Error, error_message
end
end
end
end
99 changes: 0 additions & 99 deletions lib/medium_to_webflow/webflow/client.rb

This file was deleted.

1 change: 1 addition & 0 deletions medium_to_webflow.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,5 @@ Gem::Specification.new do |spec|
spec.add_dependency "nokogiri", "~> 1.17"
spec.add_dependency "rss", "~> 0.3.1"
spec.add_dependency "thor", "~> 1.3"
spec.add_dependency "webflow-rb", "~> 1.1"
end