mirror of
https://github.com/google/pebble.git
synced 2025-03-15 16:51:21 +00:00
237 lines
7.2 KiB
Ruby
237 lines
7.2 KiB
Ruby
|
# Copyright 2025 Google LLC
|
||
|
#
|
||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
# you may not use this file except in compliance with the License.
|
||
|
# You may obtain a copy of the License at
|
||
|
#
|
||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||
|
#
|
||
|
# Unless required by applicable law or agreed to in writing, software
|
||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
# See the License for the specific language governing permissions and
|
||
|
# limitations under the License.
|
||
|
|
||
|
require 'htmlentities'
|
||
|
require 'algoliasearch'
|
||
|
require 'slugize'
|
||
|
require 'dotenv'
|
||
|
require 'securerandom'
|
||
|
|
||
|
module Jekyll
|
||
|
class GeneratorAlgolia < Generator
|
||
|
# Do this last so everything else has been processed already.
|
||
|
priority :lowest
|
||
|
|
||
|
def initialize(_config)
|
||
|
Dotenv.load
|
||
|
end
|
||
|
|
||
|
def generate(site)
|
||
|
@site = site
|
||
|
return unless check_config?
|
||
|
@prefix = site.config['algolia_prefix'] || ''
|
||
|
@random_code = random_code
|
||
|
Algolia.init(application_id: site.config['algolia_app_id'],
|
||
|
api_key: site.config['algolia_api_key'])
|
||
|
@indexes = setup_indexes
|
||
|
generate_all
|
||
|
end
|
||
|
|
||
|
private
|
||
|
|
||
|
def check_config?
|
||
|
if @site.config['algolia_app_id'].nil? || @site.config['algolia_app_id'].empty?
|
||
|
Jekyll.logger.warn(
|
||
|
'Config Warning:',
|
||
|
'You did not provide a ALGOLIA_APP_ID environment variable.'
|
||
|
)
|
||
|
return false
|
||
|
end
|
||
|
if @site.config['algolia_api_key'].nil? || @site.config['algolia_api_key'].empty?
|
||
|
Jekyll.logger.warn(
|
||
|
'Config Warning:',
|
||
|
'You did not provide a ALGOLIA_API_KEY environment variable.'
|
||
|
)
|
||
|
return false
|
||
|
end
|
||
|
true
|
||
|
end
|
||
|
|
||
|
def generate_all
|
||
|
generate_blog_posts
|
||
|
generate_guides
|
||
|
generate_documentation
|
||
|
generate_none_guide_guides
|
||
|
generate_other
|
||
|
end
|
||
|
|
||
|
def random_code
|
||
|
SecureRandom.hex
|
||
|
end
|
||
|
|
||
|
def setup_indexes
|
||
|
indexes = {}
|
||
|
@site.data['search_indexes'].each do |name, properties|
|
||
|
index = Algolia::Index.new(@prefix + name)
|
||
|
unless properties['settings'].nil?
|
||
|
index.set_settings(properties['settings'])
|
||
|
end
|
||
|
indexes[name] = index
|
||
|
end
|
||
|
indexes
|
||
|
end
|
||
|
|
||
|
def generate_documentation
|
||
|
return if @site.data['docs'].nil?
|
||
|
|
||
|
documents = @site.data['docs'][:symbols].map do |item|
|
||
|
next if item[:language] == 'c_preview'
|
||
|
|
||
|
if item[:summary].nil? || item[:summary].strip.length == 0
|
||
|
Jekyll.logger.warn(
|
||
|
'Search Warning:',
|
||
|
"There was no summary for the symbol '#{item[:name]}' in #{item[:language]}."
|
||
|
)
|
||
|
end
|
||
|
{
|
||
|
'objectID' => item[:url],
|
||
|
'title' => item[:name],
|
||
|
'splitTitle' => item[:name].split(/(?=[A-Z])/).join(' '),
|
||
|
'url' => item[:url],
|
||
|
'summary' => item[:summary],
|
||
|
'kind' => item[:kind],
|
||
|
'language' => item[:language],
|
||
|
'type' => 'documentation',
|
||
|
'ranking' => doc_language_rank[item[:language]] * 1000,
|
||
|
'randomCode' => @random_code
|
||
|
}
|
||
|
end.compact
|
||
|
@indexes['documentation'].save_objects(documents)
|
||
|
end
|
||
|
|
||
|
def generate_blog_posts
|
||
|
documents = []
|
||
|
@site.posts.docs.each do | post |
|
||
|
# Calculate the age of the post so we can prioritise newer posts
|
||
|
# over older ones.
|
||
|
# NOTE: post.date is actually a Time object, despite its name
|
||
|
age = (Time.now - post.date).round
|
||
|
author = post.data['author']
|
||
|
|
||
|
post.get_sections.each do | section |
|
||
|
# Ignore sections without any contents.
|
||
|
if section[:contents].strip.size == 0
|
||
|
next
|
||
|
end
|
||
|
|
||
|
if section[:title].nil?
|
||
|
url = post.url
|
||
|
else
|
||
|
url = post.url + '#' + section[:title].slugize
|
||
|
end
|
||
|
|
||
|
document = {
|
||
|
'objectID' => url,
|
||
|
'title' => post.data['title'],
|
||
|
'sectionTitle' => section[:title],
|
||
|
'url' => url,
|
||
|
'urlDisplay' => post.url,
|
||
|
'author' => author,
|
||
|
'content' => HTMLEntities.new.decode(section[:contents]),
|
||
|
'posted' => post.date,
|
||
|
'age' => age,
|
||
|
'type' => 'blog post',
|
||
|
'randomCode' => @random_code
|
||
|
}
|
||
|
documents << document
|
||
|
end
|
||
|
end
|
||
|
@indexes['blog-posts'].save_objects(documents)
|
||
|
end
|
||
|
|
||
|
def generate_guides
|
||
|
documents = []
|
||
|
return if @site.collections['guides'].nil?
|
||
|
|
||
|
@site.collections['guides'].docs.each do | guide |
|
||
|
group = @site.data['guides'][guide.data['guide_group']]
|
||
|
unless group.nil? || group['subgroups'].nil? || guide.data['guide_subgroup'].nil?
|
||
|
subgroup = group.nil? ? '' : group['subgroups'][guide.data['guide_subgroup']]
|
||
|
end
|
||
|
|
||
|
guide.get_sections.each do | section |
|
||
|
url = guide.url
|
||
|
unless section[:title].nil?
|
||
|
url = url + '#' + section[:title].slugize
|
||
|
end
|
||
|
|
||
|
document = {
|
||
|
'objectID' => url,
|
||
|
'title' => guide.data['title'],
|
||
|
'sectionTitle' => section[:title],
|
||
|
'url' => url,
|
||
|
'urlDisplay' => guide.url,
|
||
|
'content' => HTMLEntities.new.decode(section[:contents]),
|
||
|
'group' => group.nil? ? '' : group['title'],
|
||
|
'subgroup' => subgroup.nil? ? '' : subgroup['title'],
|
||
|
'type' => 'guide',
|
||
|
'randomCode' => @random_code
|
||
|
}
|
||
|
documents << document
|
||
|
end
|
||
|
end
|
||
|
|
||
|
@indexes['guides'].save_objects(documents)
|
||
|
end
|
||
|
|
||
|
def generate_none_guide_guides
|
||
|
documents = []
|
||
|
gs_pages = @site.pages.select { |page| page.data['search_index'] }
|
||
|
gs_pages.each do |page|
|
||
|
page.get_sections.each do |section|
|
||
|
url = page.url
|
||
|
url = url + '#' + section[:title].slugize unless section[:title].nil?
|
||
|
document = {
|
||
|
'objectID' => url,
|
||
|
'title' => page.data['title'],
|
||
|
'sectionTitle' => section[:title],
|
||
|
'url' => url,
|
||
|
'urlDisplay' => page.url,
|
||
|
'content' => HTMLEntities.new.decode(section[:contents]),
|
||
|
'group' => page.data['search_group'],
|
||
|
'subgroup' => page.data['sub_group'],
|
||
|
'type' => 'not-guide',
|
||
|
'randomCode' => @random_code
|
||
|
}
|
||
|
documents << document
|
||
|
end
|
||
|
end
|
||
|
@indexes['guides'].save_objects(documents)
|
||
|
end
|
||
|
|
||
|
def generate_other
|
||
|
documents = @site.data['search-other'].map do |other|
|
||
|
{
|
||
|
'objectID' => other['id'],
|
||
|
'title' => other['title'],
|
||
|
'url' => other['url'],
|
||
|
'content' => other['description'],
|
||
|
'randomCode' => @random_code
|
||
|
}
|
||
|
end
|
||
|
@indexes['other'].save_objects(documents)
|
||
|
end
|
||
|
|
||
|
def doc_language_rank
|
||
|
{
|
||
|
'c' => 10,
|
||
|
'rockyjs' => 9,
|
||
|
'pebblekit_js' => 8,
|
||
|
'pebblekit_android' => 6,
|
||
|
'pebblekit_ios' => 4
|
||
|
}
|
||
|
end
|
||
|
end
|
||
|
end
|