require 'fileutils'
require 'tempfile'
require 'jbuilder'
require 'json'
require 'json-schema'
require 'mini_magick'
require 'base64'
require 'open-uri'
require 'zip'
require 'uglifier'
require 'securerandom'
require 'komic/version'
require 'komic/utils'
module Komic
class ThumbnailsBuilder
def initialize(files)
@images = files
end
def render_sprite_symbol(props)
id, mime_type, data, width, height = props.values
return %(
)
end
def render_svg_sprite
sprites = @images.map.with_index do |image, index|
thumbnail = MiniMagick::Image.open(image[:src])
thumbnail.resize "x200"
thumbnail.format "jpeg"
render_sprite_symbol({
id: index,
mime_type: thumbnail.mime_type,
data: Base64.strict_encode64(thumbnail.to_blob),
width: thumbnail.width,
height: thumbnail.height
})
end
return %(
)
end
def to_build
render_svg_sprite
end
end
class ContentBuilder
def initialize(meta, files)
@meta = meta
@images = files
end
def validate_json(data)
data = JSON.load(data)
schema = JSON.load(File.read(File.join(__dir__, './content.schema.json')))
begin
JSON::Validator.validate!(schema, data)
rescue JSON::Schema::ValidationError
puts $!.message
end
end
def to_build(options)
content_builder = Jbuilder.new do |json|
json.komic_cli_version Komic::VERSION
json.content_json_version Komic::CONTENT_JSON_VERSION
json.content_json_uuid SecureRandom.uuid
json.(@meta, :name, :author, :description, :thumbnails)
json.images @images
end
data = content_builder.target!
validate_json(data)
return options[:debug] ? JSON.pretty_generate(JSON.parse(data)) : data
end
end
class Generator
def render_fake_svg(props)
width, height = props.values
return %(
)
end
def create_fake_image(filename, size)
size = Utils.parse_size(size)
file = Tempfile.new([filename, '.svg'])
image_width = size[:width]
image_height = size[:height]
file.write render_fake_svg({ width: image_width, height: image_height })
file.close
return { src: file.path, width: image_width, height: image_height }
end
def generate_mocks(options)
images = Array.new(options[:'page-number'])
.map.with_index do |value, index|
create_fake_image index.to_s, options[:size]
end
end
def create_package(data, options)
root_dir = File.join(Dir.pwd, options[:name])
image_dir = File.join(root_dir, 'images')
[root_dir, image_dir].each { |path| FileUtils.mkdir_p path }
images = data[:images]
images.map!.with_index do |image, index|
# dirty but work
if image[:src].instance_of? Tempfile
will_be_open = image[:src].path
else
will_be_open = image[:src]
end
manager = MiniMagick::Image.open(will_be_open)
image_type = manager.type.downcase
image_path = File.join(image_dir,
[index, manager.type.downcase].join('.'))
manager.quality(60)
manager.strip() unless manager.type.downcase == 'svg'
manager.write image_path
image[:src] = image_path
manager.format 'webp'
webp_path = File.join(image_dir,
[[index, 'webp'].join('-'), manager.type.downcase].join('.'))
manager.write webp_path
src = {}
src[:default] = image_type
src[image_type] = image_path
src[:webp] = webp_path
web = Utils.deep_merge_hashes(image, { src: src })
Utils.deep_merge_hashes(image, { web: web })
end
thumbnails_builder = ThumbnailsBuilder.new(images)
thumbnail_path = File.join(image_dir, './thumbnail.svg')
File.open(thumbnail_path, 'w') do |file|
file.write thumbnails_builder.to_build
end
images.map do |image|
image[:src] = Utils.get_relative_path(image[:src], root_dir)
if options[:'remote-url']
image[:src] = "https://placeimg.com/#{image[:width]}/#{image[:height]}/any"
end
image
end
meta = {
description: 'TEST',
name: 'TEST',
author: { name: 'TEST' },
thumbnails: {
height: 200,
path: Utils.get_relative_path(thumbnail_path, root_dir),
},
}
unless data[:meta].nil?
meta = Utils.deep_merge_hashes(meta, data[:meta])
end
content_builder = ContentBuilder.new(meta, images)
File.open(File.join(root_dir, './content.json'), 'w') do |file|
file.write content_builder.to_build(options)
end
end
def create_website(data, options)
root_dir = File.join(Dir.pwd, options[:name])
create_package(data, options)
dist_project = "komic-web-dist"
dist_branch = "master"
uri = "https://github.com/komic-awesome/#{dist_project}/archive/#{dist_branch}.zip"
source = open(uri)
::Zip::File.open(source.path) do |zip_file|
zip_file.each do |entry|
entry.extract(File.join(root_dir, File.basename(entry.name))) \
if File.fnmatch("#{dist_project}-#{dist_branch}/?*", entry.name)
end
end
Dir.glob("#{root_dir}/**/*.js") do |path|
uglified = Uglifier.compile(File.read(path))
File.open(path, 'w') do |file|
file.write uglified
end
end
end
end
end