Skip to content

Commit

Permalink
Using Jekyll generator
Browse files Browse the repository at this point in the history
  • Loading branch information
marcwrobel committed Dec 20, 2022
1 parent b108574 commit a301630
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 66 deletions.
12 changes: 12 additions & 0 deletions _layouts/v1_all_products.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"total": "{{ page.products | size }}",
"products": [
{% for p in page.products %}
{
"name": "{{ p.id }}",
"category": "{{ p.category }}",
"permalink": "{{ site.url }}/{{ p.id }}"
}{% unless forloop.last %},{% endunless -%}
{%- endfor %}
]
}
25 changes: 25 additions & 0 deletions _layouts/v1_product.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"title": "{{ page.title }}",
"category": "{{ page.category }}",
"iconSlug": "{{ page.iconSlug | default: page.id }}",
"permalink": "{{ site.url }}/{{ p.id }}",
"versionCommand": "{{ page.versionCommand }}",
"releasePolicyLink": "{{ page.releasePolicyLink }}",
"auto": {% if page.auto %}true{% else %}false{% endif %},
"releases": [
{% for r in page.releases %}
{
"cycle": "{{ r.releaseCycle }}",
"codename": {% if r.codename %}"{{ r.codename }}"{% else %}null{% endif %},
"releaseDate": "{{ r.releaseDate }}",
"support": {% if r.support %}"{{ r.support }}"{% else %}null{% endif %},
"eol": {% if r.eol %}"{{ r.eol }}"{% else %}null{% endif %},
"latest": {% if r.latest %}"{{ r.latest }}"{% else %}null{% endif %},
"latestReleaseDate": {% if r.latestReleaseDate %}"{{ r.latestReleaseDate }}"{% else %}null{% endif %},
"lts": {% if r.lts %}{{ r.lts }}{% else %}false{% endif %},
"discontinued": {% if r.diconstinued %}{{ r.discontinued }}{% else %}false{% endif %},
"link": {% if r.link %}"{{ r.link }}"{% else %}null{% endif %}
}{% unless forloop.last %},{% endunless -%}
{%- endfor %}
]
}
112 changes: 46 additions & 66 deletions _plugins/generate-api-v1.rb
Original file line number Diff line number Diff line change
@@ -1,89 +1,69 @@
#!/usr/bin/env ruby

# This script creates API files for version 1 of the endoflife.date API.
#
# There are three kind of generated files :
# - all.json: contains the list of all the product names.
# - <product>.json: contains a given product data ()including releases data).
# - <product>/<release>.json: contains a given product release data.

require 'fileutils'
require 'json'
require 'yaml'
require 'date'
require 'jekyll'

module ApiV1

# This API path
DIR = 'api/v1'
class ApiGenerator < Jekyll::Generator
safe true
priority :lowest

# Returns the path of a file inside the API namespace.
def self.file(name, *args)
File.join(DIR, name, *args)
end
def generate(site)
all_products = []

# Holds information about a product.
Product = Class.new do
attr_accessor :data
site.pages.each do |page|
is_markdown = (page.name.end_with?("md"))
has_permalink = (page.data.has_key? 'permalink')
has_releases = (page.data.has_key? 'releases')
is_product_page = (is_markdown and has_permalink and has_releases)

# Initializes the product with the given product's markdown file.
# The markdown file is expected to contain a YAML front-matter with the appropriate properties.
#
# Copying the data makes it easier to process it.
def initialize(data)
@data = Hash.new
# The product name is derived from the product's permalink (ex. /debian => debian).
@data["name"] = data['permalink'][1..data['permalink'].length]
@data["title"] = data['title']
@data["category"] = data['category']
@data["iconSlug"] = data['iconSlug']
@data["permalink"] = data['permalink']
@data["versionCommand"] = data['versionCommand']
@data["auto"] = data.has_key? 'auto'
@data["releasePolicyLink"] = data['releasePolicyLink']
@data["releases"] = data['releases'].map do |release|
release_data = Hash.new
release_data["name"] = release['releaseCycle']
release_data["codename"] = release['codename']
release_data["releaseDate"] = release['releaseDate']
release_data["support"] = release['support']
release_data["eol"] = release['eol']
release_data["discontinued"] = release['discontinued']
release_data["lts"] = release['lts'] || false # lts is optional, make sure it always has a value
release_data["latest"] = release['latest']
release_data["latestReleaseDate"] = release['latestReleaseDate']
release_data
if is_product_page
product_page = ProductJson.new(site, page)
site.pages << product_page
all_products << product_page
end
end
end

def name
data["name"]
site.pages << AllProductsJson.new(site, all_products)
end
end
end

product_names = []
FileUtils.mkdir_p(ApiV1::file('.'))
class ProductJson < Jekyll::Page
def initialize(site, product)
id = product.data['permalink'][1..product.data['permalink'].length]

Dir['products/*.md'].each do |file|
# Load and prepare data
raw_data = YAML.safe_load(File.open(file), permitted_classes: [Date])
product = ApiV1::Product.new(raw_data)
product_names.append(product.name)
@site = site
@base = site.source
@dir = 'api/v1'
@name = "#{id}.json"

# Write /<product>.json
product_file = ApiV1::file("#{product.name}.json")
File.open(product_file, 'w') { |f| f.puts product.data.to_json }
@data = {}.merge(product.data)
@data.delete('permalink') # path already configured above, must not be overridden
@data.delete('alternate_urls') # no need for API
@data['layout'] = 'v1_product'
@data['id'] = id # name is already a page attribute

# Write all /<product>/<release>.json
FileUtils.mkdir_p(ApiV1::file(product.name))
product.data["releases"].each do |release|
# Any / characters in the name are replaced with - to avoid file errors.
release_file = ApiV1::file(product.name, "#{release['name'].to_s.tr('/', '-')}.json")
File.open(release_file, 'w') { |f| f.puts release.to_json }
self.process(@name)
end
end
end

# Write /all.json
all_products_file = ApiV1::file('all.json')
File.open(all_products_file, 'w') { |f| f.puts product_names.sort.to_json }
class AllProductsJson < Jekyll::Page
def initialize(site, all_products)
@site = site
@base = site.source
@dir = 'api/v1'
@name = "all.json"

@data = {}
@data['layout'] = 'v1_all_products'
@data['products'] = all_products ? all_products : []

self.process(@name)
end
end
end

0 comments on commit a301630

Please sign in to comment.