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
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()
|
|
|