TsMediaPage is a static web site generator for multimedia pages.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

248 lines
7.9 KiB

#!/usr/bin/env ruby
# This file is part of TsMediaPage
# Copyright (C) 2017-2021 Moritz Strohm <ncc1988@posteo.de>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
require 'erb'
require 'singleton'
require 'thread'
require_relative('./Config.rb')
require_relative('./Metadata.rb')
module TsMediaPage
class OrgPage
attr_accessor :page_title
attr_accessor :page_link
attr_accessor :metadata
attr_accessor :output_file_name
def initialize(
website_title = '',
page_title = '',
output_file_name = '',
categories = Array.new(),
description = '',
items = Hash.new()
)
@config = TsMediaPage::Config.instance()
@metadata = TsMediaPage::Metadata.new()
@metadata.title = page_title
@metadata.description = description
@metadata.categories = categories
@output_file_name = output_file_name
@page_title = page_title
@page_link = './' +
File.basename(@output_file_name) +
'.html'
#The following is a very basic implementation
#which can generate a very very long index.html.
#But it's good enough for the first versions of TsMediaPage.
#Besides, it's pre-alpha software ;)
#TODO: make the path configurable and split indexes to
#several files if the file lists become very big.
base_template = IO.read(
File.expand_path('./themes/' +
@config.theme +
'/base.html')
)
content_template = IO.read(
File.expand_path('./themes/' +
@config.theme +
'/org_page.html')
)
@base_erb = ERB.new(base_template)
@content_erb = ERB.new(content_template)
@website_title = website_title
@categories = categories
@description = description
@items = items
@content = ''
end
def generate()
@content = @content_erb.result(binding)
return @base_erb.result(binding)
end
end
class OrgPageGenerator
include Singleton
def initialize()
@mutex = Mutex.new()
@page_index = []
@categories = {}
@config = TsMediaPage::Config.instance()
end
##
# This method adds a page to the internal list of
# the OrgPageGenerator. This method is thread safe.
def addPage(page = nil)
if (!page)
return false
end
if (!page.output_file_name or !page.page_link or
!page.metadata.title)
#We need the page link, the output file name
#and the title!
puts 'page_link: ' + page.page_link.to_s()
puts 'output_file_name: ' + page.output_file_name.to_s()
puts 'title: ' + page.metadata.title.to_s()
return false
end
# Since this method is called from threads (indirectly)
# we must control the access to the page lists:
title = page.metadata.title
@mutex.synchronize() {
#Extract the first letter of the file name.
#The indexes for categories and the general index
#are sorted by first letter if they become too long.
first_letter = title.strip()[0]
if (!@page_index.is_a?(Array))
@page_index = []
end
#Add the page to the general page index:
@page_index.push(page)
if (page.metadata.categories)
page.metadata.categories.each { |category|
#Add the page to the category index:
if (!@categories[category].is_a?(Hash))
@categories[category] = {}
end
if (!@categories[category][first_letter].is_a?(Array))
@categories[category][first_letter] = []
end
@categories[category][first_letter].push(page)
}
end
}
end
def generateIndexes()
#Generate the general index with the n newest items first.
@page_index.sort_by! { |page|
next page.metadata.date.to_i()
}
@page_index = @page_index.slice(0, 20) #TODO: make element amount configurable
#To have an unified format for each org page content,
#we convert the page index to a hash.
hashed_page_index = {
nil => @page_index
}
#generate template:
index_page = OrgPage.new(
@config.website_title,
'Index',
'index.html',
nil,
@description,
hashed_page_index
)
index_file = File.open(
File.expand_path(@config.output_path) +
'/index.html',
'w'
)
index_file.write(index_page.generate())
#Generate the category overview page and build the
#category index:
letter_sorted_categories = {}
@categories.each { |category_name, letter_sorted_pages|
first_letter = category_name[0].upcase()
if (!letter_sorted_categories[first_letter].is_a?(Array))
letter_sorted_categories[first_letter] = []
end
#generate template:
cat_page = OrgPage.new(
@config.website_title,
category_name,
category_name + '.category',
nil,
'',
letter_sorted_pages
)
cat_file = File.open(
File.expand_path(@config.output_path) +
'/' + category_name + '.category.html',
'w'
)
cat_file.write(cat_page.generate())
#modify the page title for the category index:
cat_page.page_title = category_name
letter_sorted_categories[first_letter].push(cat_page)
}
#Sort the category index: TODO: repair
#letter_sorted_categories.each { |letter_content|
# letter_content.sort_by! { |category|
# next category.page_title
# }
#}
cat_index_page = OrgPage.new(
@config.website_title,
'Category index',
'categories.index.html',
nil,
'',
letter_sorted_categories
)
cat_index_file = File.open(
File.expand_path(@config.output_path) +
'/categories.index.html',
'w'
)
cat_index_file.write(cat_index_page.generate())
return true
end
end
end