From d131a62457c15adb2e434533a0c6ebf88d5bd599 Mon Sep 17 00:00:00 2001 From: Pixelastic Date: Mon, 13 Nov 2017 12:57:14 +0100 Subject: [PATCH] Adding getters for app id, api key and index name --- jeremy.rb | 46 ----- lib/jekyll-algolia.rb | 3 + lib/jekyll/algolia/configurator.rb | 38 ++++ lib/jekyll/algolia/logger.rb | 7 + lib_old/record_extractor.rb | 180 ------------------- spec/jekyll/algolia/configurator_spec.rb | 68 ++++++- spec/site/{api_key_dir => }/_algolia_api_key | 0 7 files changed, 110 insertions(+), 232 deletions(-) delete mode 100644 jeremy.rb create mode 100644 lib/jekyll/algolia/logger.rb delete mode 100644 lib_old/record_extractor.rb rename spec/site/{api_key_dir => }/_algolia_api_key (100%) diff --git a/jeremy.rb b/jeremy.rb deleted file mode 100644 index 5c0b482..0000000 --- a/jeremy.rb +++ /dev/null @@ -1,46 +0,0 @@ -module AlgoliaPlugin - def self.do_something(config) - site = Jekyll::Site.new(config) - site.process - 42 - end -end - -describe AlgoliaPlugin do - describe '.do_something' do - let(:config) { {foo: 'bar'} } - let(:jekyll_site) { double('Jekyll::Site', process: nil) } - before { expect(Jekyll::Site).to receive(:new).with(config).and_return(jekyll_site) } - before { expect(jekyll_site).to receive(:process) } - - it { AlgoliaPlugin.do_something(config) } - - end - describe '.do_something' do - let(:config) { {foo: 'bar'} } - let(:jekyll_site) { double('Jekyll::Site', process: nil) } - before { allow(Jekyll::Site).to receive(:new).and_return(jekyll_site) } - before { allow(jekyll_site).to receive(:process) } - - before { AlgoliaPlugin.do_something(config) } - - it { expect(Jekyll::Site).to have_received(:new).with(config) } - it { expect(jekyll_site).to have_received(:process).with(config) } - - - end - describe '.do_something' do - let(:config) { {foo: 'bar'} } - let(:jekyll_site) { double('Jekyll::Site', process: nil) } - before { allow(Jekyll::Site).to receive(:new).and_return(jekyll_site) } - before { allow(jekyll_site).to receive(:process) } - - subject { AlgoliaPlugin.do_something(config) } - - context 'config is valid' do - let(:config) { false } - it { should eq 42 } - it { expect(subject).to eq 42 } - end - end -end diff --git a/lib/jekyll-algolia.rb b/lib/jekyll-algolia.rb index eaaf44a..7bde03d 100644 --- a/lib/jekyll-algolia.rb +++ b/lib/jekyll-algolia.rb @@ -8,6 +8,7 @@ module Jekyll require 'jekyll/algolia/utils' require 'jekyll/algolia/user_hooks' require 'jekyll/algolia/configurator' + require 'jekyll/algolia/logger' require 'jekyll/algolia/file_browser' require 'jekyll/algolia/extractor' require 'jekyll/algolia/indexer' @@ -25,6 +26,8 @@ module Jekyll @config = config @site = Jekyll::Site.new(@config) monkey_patch_site(@site) + + Jekyll::Algolia::Configurator.assert_valid_credentials # @checker = AlgoliaSearchCredentialChecker.new(@config) self end diff --git a/lib/jekyll/algolia/configurator.rb b/lib/jekyll/algolia/configurator.rb index 84fe0ad..7fe0d4b 100644 --- a/lib/jekyll/algolia/configurator.rb +++ b/lib/jekyll/algolia/configurator.rb @@ -36,6 +36,44 @@ module Jekyll value end + # Public: Return the application id + # + # Will first try to read the ENV variable, and fallback to the one + # configured in Jekyll config + def self.application_id + ENV['ALGOLIA_APPLICATION_ID'] || algolia('application_id') + end + + # Public: Return the api key + # + # Will first try to read the ENV variable. Will otherwise try to read the + # _algolia_api_key file in the Jekyll folder + def self.api_key + # Alway taking the ENV variable first + return ENV['ALGOLIA_API_KEY'] if ENV['ALGOLIA_API_KEY'] + + # Reading from file on disk otherwise + source_dir = get('source') + if source_dir + api_key_file = File.join(source_dir, '_algolia_api_key') + if File.exist?(api_key_file) && File.size(api_key_file) > 0 + return File.open(api_key_file).read.strip + end + end + + nil + end + + # Public: Return the index name + # + # Will first try to read the ENV variable, and fallback to the one + # configured in Jekyll config + def self.index_name + ENV['ALGOLIA_INDEX_NAME'] || algolia('index_name') + end + + def self.assert_valid_credentials; end + # Public: Setting a default values to index only html and markdown files # # Markdown files can have many different extensions. We keep the one diff --git a/lib/jekyll/algolia/logger.rb b/lib/jekyll/algolia/logger.rb new file mode 100644 index 0000000..ed2a75b --- /dev/null +++ b/lib/jekyll/algolia/logger.rb @@ -0,0 +1,7 @@ +module Jekyll + module Algolia + # Display helpful error messages + module Logger + end + end +end diff --git a/lib_old/record_extractor.rb b/lib_old/record_extractor.rb deleted file mode 100644 index daa559e..0000000 --- a/lib_old/record_extractor.rb +++ /dev/null @@ -1,180 +0,0 @@ -require 'algoliasearch' -require 'nokogiri' -require 'json' -require 'algolia_html_extractor' - -# Given an HTML file as input, will return an array of records to index -class AlgoliaSearchRecordExtractor - attr_reader :file - - def initialize(file) - @file = file - @config = file.site.config - default_config = { - 'nodes_to_index' => 'p' - } - @config = default_config.merge(file.site.config['algolia']) - end - - # Hook to modify a record after extracting - def custom_hook_each(item, _node) - item - end - - # Hook to modify all records after extracting - def custom_hook_all(items) - items - end - - ## - # Return the type of the Jekyll element - # It can be either page, post or document - def type - classname = @file.class.name - subclass = classname.split('::')[1] - type = subclass.downcase - - # Post are actually a specific type of Documents - if type == 'document' - collection_name = @file.collection.label - return 'post' if collection_name == 'posts' - end - - type - end - - ## - # Return the url of the page - def url - @file.url - end - - ## - # Return the title of the page - def title - @file.data['title'] - end - - ## - # Returns the slug of the document - def slug - # We can guess the slug from the filename for all documents - basename = File.basename(@file.path) - extname = File.extname(basename) - slug = File.basename(basename, extname) - - # Jekyll v3 posts have it in data - return @file.data['slug'] if @file.data.key?('slug') - - # Jekyll v2 posts have a specific slug method - return @file.slug if @file.respond_to?(:slug) - - slug - end - - ## - # Get an array of tags of the document - def tags - tags = [] - - has_tags_data = @file.data.key?('tags') - - # All tags are in data['tags'] - tags = @file.data['tags'] if has_tags_data - - # Some extension extends the tags with custom classes, so we make sure we - # cast them as strings - tags.map(&:to_s) - end - - ## - # Get the post date timestamp - def date - return nil unless @file.respond_to?(:date) - - @file.date.to_time.to_i - end - - ## - # Get the collection name of a document - def collection - return nil unless @file.respond_to?(:collection) - - collection_name = @file.collection.label - - # In Jekyll v3, posts are actually a collection - return nil if collection_name == 'posts' - collection_name - end - - ## - # Get a hash of all front-matter data - def front_matter - raw_data = @file.data - - # We clean some keys that will be handled by specific methods - attributes_to_remove = %w(title tags slug url date type) - attributes_to_remove.each do |attribute| - raw_data.delete(attribute) - end - - # Convert to symbols - data = {} - raw_data.each do |key, value| - data[key.to_sym] = value - end - - data - end - - ## - # Get the list of all node data - def hierarchy_nodes - extractor_options = { - css_selector: @config['nodes_to_index'] - } - - AlgoliaHTMLExtractor.new( - @file.content, - options: extractor_options - ).extract - end - - # Extract all records from the page and return the list - def extract - # Getting all hierarchical nodes from the HTML input - raw_items = hierarchy_nodes - - # Shared attributes relative to the page that all records will have - shared_attributes = { - type: type, - url: url, - title: title, - slug: slug, - date: date, - collection: collection, - tags: tags - } - # Remove empty attributes - shared_attributes = shared_attributes.delete_if do |_, value| - value.nil? - end - - # Enriching with page metadata - items = [] - raw_items.each do |raw_item| - nokogiri_node = raw_item[:node] - raw_item.delete(:node) - item = shared_attributes.merge(raw_item) - item[:objectID] = item[:uuid] - item.delete(:uuid) - - item = custom_hook_each(item, nokogiri_node) - next if item.nil? - - items << item - end - - custom_hook_all(items) - end -end diff --git a/spec/jekyll/algolia/configurator_spec.rb b/spec/jekyll/algolia/configurator_spec.rb index 2cc986e..a51d4f4 100644 --- a/spec/jekyll/algolia/configurator_spec.rb +++ b/spec/jekyll/algolia/configurator_spec.rb @@ -1,8 +1,8 @@ -# rubocop:disable Metrics/BlockLength require 'spec_helper' describe(Jekyll::Algolia::Configurator) do let(:current) { Jekyll::Algolia::Configurator } + let(:config) { {} } before do allow(Jekyll::Algolia).to receive(:config).and_return(config) end @@ -46,7 +46,6 @@ describe(Jekyll::Algolia::Configurator) do end context 'with no algolia config defined' do - let(:config) { {} } let(:input) { 'foo' } it { should eq nil } @@ -58,8 +57,6 @@ describe(Jekyll::Algolia::Configurator) do end describe '.default_extensions_to_index' do - let(:config) { {} } - subject { current.default_extensions_to_index } before do @@ -75,8 +72,6 @@ describe(Jekyll::Algolia::Configurator) do end describe '.default_files_to_exclude' do - let(:config) { {} } - subject { current.default_files_to_exclude } before do @@ -89,4 +84,65 @@ describe(Jekyll::Algolia::Configurator) do it { should include('index.foo') } it { should include('index.bar') } end + + describe '.index_name' do + subject { current.index_name } + + describe 'should return nil if none configured' do + it { should eq nil } + end + describe 'should return the value in _config.yml if set' do + let(:config) { { 'algolia' => { 'index_name' => 'foo' } } } + it { should eq 'foo' } + end + describe 'should return the value in ENV is set' do + before { stub_const('ENV', 'ALGOLIA_INDEX_NAME' => 'bar') } + it { should eq 'bar' } + end + describe 'should prefer the value in ENV rather than config if set' do + let(:config) { { 'algolia' => { 'index_name' => 'foo' } } } + before { stub_const('ENV', 'ALGOLIA_INDEX_NAME' => 'bar') } + it { should eq 'bar' } + end + end + + describe '.application_id' do + subject { current.application_id } + + describe 'should return nil if none configured' do + it { should eq nil } + end + describe 'should return the value in _config.yml if set' do + let(:config) { { 'algolia' => { 'application_id' => 'foo' } } } + it { should eq 'foo' } + end + describe 'should return the value in ENV is set' do + let(:config) { {} } + before { stub_const('ENV', 'ALGOLIA_APPLICATION_ID' => 'bar') } + it { should eq 'bar' } + end + describe 'should prefer the value in ENV rather than config if set' do + let(:config) { { 'algolia' => { 'application_id' => 'foo' } } } + before { stub_const('ENV', 'ALGOLIA_APPLICATION_ID' => 'bar') } + it { should eq 'bar' } + end + end + + describe '.api_key' do + subject { current.api_key } + + describe 'should return nil if none configured' do + it { should eq nil } + end + describe 'should return the value in ENV is set' do + before { stub_const('ENV', 'ALGOLIA_API_KEY' => 'bar') } + it { should eq 'bar' } + end + describe 'should return the value in _algolia_api_key file' do + let(:config) { { 'source' => './spec/site' } } + it { should eq 'APIKEY_FROM_FILE' } + end + describe 'should prefer the value in ENV rather than in the file' do + end + end end diff --git a/spec/site/api_key_dir/_algolia_api_key b/spec/site/_algolia_api_key similarity index 100% rename from spec/site/api_key_dir/_algolia_api_key rename to spec/site/_algolia_api_key