lib/jekyll/airtable_fetcher.rb in jekyll-airtable-0.3.0 vs lib/jekyll/airtable_fetcher.rb in jekyll-airtable-0.4.1

- old
+ new

@@ -1,53 +1,53 @@ require "json" require 'fileutils' require 'yaml' +require 'hashie' +require 'uri' module Jekyll class AirtableFetcher < Jekyll::Generator safe true priority :lowest def generate(site) - return false if site.config['AIRTABLE_API_KEY'].nil? || site.config['AIRTABLE_API_KEY'] == '' - return false if site.config['SYNC_WITH_AIRTABLE'] == 'false' - - setup_directories + jekyll_config = Hashie::Mash.new(site.config) + return false if should_generate_be_prevented?(jekyll_config) # For storing hashes of attachments that will be saved to the data file @attachments_hash = {} + setup_directories - Airtable.configure do |config| - config.api_key = site.config['AIRTABLE_API_KEY'] - end + client = setting_up_airtable_client - client = Airtable.client(base_uid: site.config['AIRTABLE_BASE_UID']) - - site.config['AIRTABLE_TABLE_NAMES'].each do |table_name| + @table_names.each do |table_name| records = client.list_records(table_name: table_name) next if records.size == 0 + + if records.class.name == 'Hash' + error = records["error"] + if error.present? + puts error['message'] + next + end + end directory_name = "collections/_" + to_snake(table_name) Dir.mkdir(directory_name) unless File.exists?(directory_name) records.each do |record| fields = record['fields'] - # We use the first field as the primary key - # Then find the value of the primary key to be stored as the slug, which - # will be used as file name and the path to the record in the url. - # However, if the record has field called 'slug', it will be used instead - pkey = fields.keys.first - slug = fields['slug'].nil? ? fields[pkey] : fields['slug'] - filename = to_snake(slug) + '.md' uid = record['id'] + out_file = create_page_for_the_record(directory_name, uid, fields) - out_file = File.new("#{directory_name}/#{filename}", "w") - out_file.puts(front_matter_mark) - out_file.puts("uid: #{uid}") - fields.each do |key, value| snake_key = to_snake(key) + if is_a_long_text?(jekyll_config, table_name, key) + write_long_text_to_file(snake_key, value, out_file) + next + end + if value.class.name == 'Array' out_file.puts("#{snake_key}:") write_array_values(out_file, value) else value = stringify_value_if_necessary(value) @@ -60,23 +60,45 @@ out_file.close end end - write_attachments_data_file + write_attachments_data_file if @attachments_hash.keys.size > 0 end private + def should_generate_be_prevented?(config) + is_enabled = config.airtable.enable_sync + return true if !is_enabled + + @api_key = config.to_hash['AIRTABLE_API_KEY'] + @base_uid = config.airtable.base_uid + @table_names = config.airtable.tables.map{ |t| t.name } + + return true if @api_key.nil? || @api_key == '' || @base_uid.nil? || @base_uid == '' + false + end + + def setting_up_airtable_client + Airtable.configure { |config| config.api_key = @api_key } + + Airtable.client(base_uid: @base_uid) + end + def front_matter_mark '---' end def to_snake(string) string.split(' ').map(&:downcase).join('_') end + def to_dash(string) + string.split(' ').map(&:downcase).join('-') + end + def write_array_values(file, array) array.each do |element| if is_this_is_an_attachment?(element) # Store only the uid of the attachment in the front matter value = element['id'] @@ -111,15 +133,68 @@ def setup_directories Dir.mkdir('_data') unless File.exists?('_data') Dir.mkdir('_data/airtable') unless File.exists?('_data/airtable') - Dir.mkdir('collections') unless File.exists?('collections') + Dir.mkdir('collections') unless File.exists?('collections') end def write_attachments_data_file File.open("_data/airtable/attachments.yml", "w") do |f| f.write(@attachments_hash.to_yaml) end end + + def create_page_for_the_record(directory_name, uid, fields) + # We use the first field as the primary key + # Then find the value of the primary key to be stored as the slug, which + # will be used as file name and the path to the record in the url. + # However, if the record has field called 'slug', it will be used instead + pkey = fields.keys.first + slug = fields['slug'].nil? ? fields[pkey] : fields['slug'] + slug = slug.length > 100 ? uid : slug + + if is_an_uri?(slug) + filename = to_dash(slug) + '.md' + else + filename = to_dash(uid) + '.md' + end + + out_file = File.new("#{directory_name}/#{filename}", "w") + out_file.puts(front_matter_mark) + out_file.puts("uid: #{uid}") + + out_file + end + + def is_a_long_text?(config, table_name, key) + table = config.airtable.tables.select{ |a| a.name == table_name }.first + return false if table.nil? + + list = table.long_text_columns || [] + list.include?(key) + end + + def write_long_text_to_file(snake_key, text, out_file) + out_file.puts("#{snake_key}: |") + + lines = text.split("\n") + + lines.each do |line| + out_file.puts(" " + line) + end + end + + def is_an_uri?(string) + return true if string.include?('http') || + string.include?('://') || + string.include?('www.') + + uri = URI.parse(string) + %w( http https ).include?(uri.scheme) + rescue URI::BadURIError + false + rescue URI::InvalidURIError + false + end end end