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.
 
 
 

297 lines
11 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 'fileutils'
require_relative('./Config.rb')
require_relative('./MediaConverter.rb')
#TODO: require './MediaCategoryHandler.rb'
module TsMediaPage
class Main
#Include GetText and bind translations:
include GetText
bindtextdomain('TsMediaPage', :path => TsMediaPage::LOCALE_PATH)
def self.printHelp()
puts(
_("Usage: tsmediapage.rb [ARGUMENTS]\n" +
"The following arguments are defined:\n" +
"--version\t\tPrints the version of TsMediaPage.\n" +
"-h, --help\t\tPrints this help text.\n" +
"--create-missing-stuff\tCreate the default configuration in the current directory.\n" +
"-j<n>\t\t\tNumber of jobs for the media conversion.\n" +
"\t\t\tExample: -j2 will use 2 jobs for media conversion.\n" +
"\t\t\tBy default TsMediaPage uses one job for media conversion.\n"
)
)
end
def self.printVersion()
puts(
sprintf(
_('TsMediaPage Version %s'),
TsMediaPage::TSMEDIAPAGE_VERSION
)
)
puts('Copyright 2017-2019 Moritz Strohm')
end
##
# This is the "core" function of TsMediaPage.
# It is responsible for processing all the media files
# and generating media pages for them.
def self.processMediaFile(file_name)
#First we check if the file is readable:
#TODO
#Then we init a MediaConverter for the file.
#The MediaConverter instance will also read
#the file's metadata from a .meta file:
converter = TsMediaPage::MediaConverter.new(file_name)
#After that we create a MediaConverter instance for the file
#and start the media file conversion:
conversion_result = converter.convertFile()
#If the media file has been converted successfully we can
#generate its html page:
if (conversion_result)
converter.generateMediaPage()
else
puts(
sprintf(
_('Error while converting file "%s"!'),
file_name
)
)
end
end
##
# The main function.
def self.main()
#Convert media with one thread by default:
num_threads = 1
#Handle command line arguments first:
if (ARGV.length)
#At least one argument is given:
ARGV.each { |argument|
if (argument.start_with?('-j'))
#The amount of jobs (threads) is specified.
num_threads = argument.slice(/[0-9]+/).to_i()
if (num_threads < 1)
puts(_('Error: The number of jobs cannot be less than one!'))
exit(1)
end
puts(
sprintf(
_('Number of jobs has been set to %d.'),
num_threads
)
)
elsif ((argument == '-h') or (argument == '--help'))
self.printHelp()
elsif (argument == '--version')
self.printVersion()
elsif (argument == '--create-missing-stuff')
#Write default configuration:
config = TsMediaPage::Config.instance()
if (config.save('./TsMediaPage.config'))
exit(0)
else
exit(1)
end
end
}
end
#Load the configuration. If it cannot be found
#in the current directory load it from the .config
#directory of the current user. If the configuration
#cannot be loaded from there, save the default
#configuration in the current directory.
config = TsMediaPage::Config.instance()
if (!config.load('./TsMediaPage.config'))
if (!config.load('~/.config/TsMediaPage.config'))
puts(
_(
'TsMediaPage cannot load the configuration.' +
'To generate a default configuration in the current directory ' +
'use the parameter --create-missing-stuff.'
)
)
exit(1)
end
end
if (!Dir.exist?(File.expand_path(config.source_path)))
puts(
sprintf(
_('Error: Source path "%s" does not exist!'),
File.expand_path(config.source_path)
)
)
exit(1)
end
if (!Dir.exist?(File.expand_path(config.output_path)))
puts(
sprintf(
_('Error: Output path "%s" does not exist!'),
File.expand_path(config.output_path)
)
)
exit(1)
end
#Get a list with all media files in the source directory:
unprocessed_files = Dir.glob(
File.expand_path(config.source_path) +
'/**/*\.{ogg,flac,opus,spx,mp3,m4a,aac,wav,ogv,webm,mp4,avi,mpg,dv,mkv,jpg,svg,png}'
)
if (unprocessed_files.empty?())
puts(
sprintf(
_('Your source directory "%s" is empty. ' +
'Nothing to be done for TsMediaPage.'),
File.expand_path(config.source_path)
)
)
exit(0)
end
todo_lists = []
#Split file list so that each thread has its own
#separate file list:
i = 0
unprocessed_files.each { |item|
if (!todo_lists[i % num_threads].is_a?(Array))
todo_lists[i % num_threads] = []
end
todo_lists[i % num_threads] << item
i += 1
}
#puts('DEBUG: todo_lists:' + todo_lists.to_s())
#Start the threads:
threads = []
num_threads.times do |i|
thread_todo_list = todo_lists[i]
if (thread_todo_list)
threads << Thread.new {
thread_todo_list.each { |file_name|
self.processMediaFile(file_name)
}
}
end
end
#Wait until all threads have finished:
threads.each { |thread|
thread.join
}
#Now we generate the index and category pages:
org_generator = TsMediaPage::OrgPageGenerator.instance()
org_generator.generateIndexes()
#Finally we must copy the stylesheets of the theme:
css_file_path = '/themes/' + config.theme + '/'
layout_file_path = css_file_path + 'layout_' + config.layout + '.css'
colour_scheme_file_path = css_file_path + + 'colour_scheme_' +
config.colour_scheme + '.css'
print(_('Merging stylesheets...'))
if (File.exists?('.' + layout_file_path))
#The css file is in the themes folder of the current directory.
layout_file_path = '.' + layout_file_path
elsif(File.exists?('~/.config/TssWiki/' + layout_file_path))
#The css file is in the config folder in the home directory:
layout_file_path = '~/.config/TssWiki/' + layout_file_path
else
puts(_('ERROR: Cannot find layout stylesheet!'))
exit(1)
end
if (File.exists?('.' + colour_scheme_file_path))
#The css file is in the themes folder of the current directory.
colour_scheme_file_path = '.' + colour_scheme_file_path
elsif(File.exists?('~/.config/TssWiki/' + colour_scheme_file_path))
#The css file is in the config folder in the home directory:
colour_scheme_file_path = '~/.config/TssWiki/' + colour_scheme_file_path
else
puts(_('ERROR: Cannot find colour scheme stylesheet!'))
exit(1)
end
output_css_file_path = config.output_path + '/style.css'
merge_css = false
if (!File.exist?(output_css_file_path))
merge_css = true
elsif ((File.mtime(layout_file_path) > File.mtime(output_css_file_path)) or
(File.mtime(colour_scheme_file_path) > File.mtime(output_css_file_path))
)
#The layout or colour scheme CSS source files are newer than the
#combined CSS output file.
merge_css = true
elsif (config.mtime > File.mtime(output_css_file_path))
#The configuration has changed. The CSS file should be generated.
merge_css = true
end
if (merge_css)
#We start by copying the layout file:
FileUtils.cp(layout_file_path, output_css_file_path)
#Now we append the colour scheme file:
output_file = File.new(output_css_file_path, 'a')
colour_scheme_file = File.new(colour_scheme_file_path, 'r')
content = colour_scheme_file.read()
output_file.write(content)
end
puts(_('DONE'))
#Finished!
puts(
sprintf(
_('Your media page "%s" has been generated!'),
config.website_title
)
)
end
end
end
TsMediaPage::Main.main()