From 425eadee63aac5b24574935418810da1656c4fa4 Mon Sep 17 00:00:00 2001 From: Neetpone <132411956+Neetpone@users.noreply.github.com> Date: Tue, 30 Jul 2024 13:44:41 -0400 Subject: [PATCH] feat(downloads): improve epub generation --- .rubocop.yml | 4 ---- app/controllers/chapters_controller.rb | 2 +- .../stories/downloads_controller.rb | 4 ++-- app/lib/ebook/epub_generator.rb | 24 +++++++++++++++++-- app/lib/ebook/templates/chapter.html.slim | 6 ++--- app/lib/story_renderer.rb | 3 ++- app/views/stories/show.html.slim | 2 ++ config/application.rb | 1 + 8 files changed, 33 insertions(+), 13 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 1262bf0..b3b9dd4 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -61,7 +61,3 @@ Style/NumericPredicate: # I've always been an "unnecessary this->" guy myself. Style/RedundantSelf: Enabled: false - -# Story downloads rely on this. -Rails/RenderInline: - Enabled: false \ No newline at end of file diff --git a/app/controllers/chapters_controller.rb b/app/controllers/chapters_controller.rb index 077644c..b5effd0 100644 --- a/app/controllers/chapters_controller.rb +++ b/app/controllers/chapters_controller.rb @@ -6,6 +6,6 @@ class ChaptersController < ApplicationController @story = Story.find(params[:story_id]) @chapter = @story.chapters.find_by(number: params[:id]) - @rendered_html = StoryRenderer.render_chapter(@chapter) + @rendered_html = Ebook::EpubGenerator.render_chapter(@chapter) end end diff --git a/app/controllers/stories/downloads_controller.rb b/app/controllers/stories/downloads_controller.rb index f6f471f..53db38a 100644 --- a/app/controllers/stories/downloads_controller.rb +++ b/app/controllers/stories/downloads_controller.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class Stories::DownloadsController < ApplicationController MIME_TYPES = { - text: 'text/plain', + txt: 'text/plain', html: 'text/html', epub: 'application/x-epub' }.freeze @@ -12,6 +12,6 @@ class Stories::DownloadsController < ApplicationController format = MIME_TYPES.keys.detect { |fmt| fmt.to_s == params[:fmt] } || :text renderer = StoryRenderer.new @story - render inline: renderer.send(format), content_type: MIME_TYPES[format], content_disposition: 'attachment' + send_data renderer.send(format), type: MIME_TYPES[format], disposition: :attachment, filename: "#{@story.title}.#{format}" end end diff --git a/app/lib/ebook/epub_generator.rb b/app/lib/ebook/epub_generator.rb index e0c1354..df76e3c 100644 --- a/app/lib/ebook/epub_generator.rb +++ b/app/lib/ebook/epub_generator.rb @@ -1,4 +1,5 @@ require 'gepub' +require 'ostruct' TEMPLATE_DIRECTORY = Rails.root.join('app/lib/ebook') @@ -24,7 +25,7 @@ class Ebook::EpubGenerator end end - book + book.generate_epub_stream.string end #private @@ -38,6 +39,25 @@ class Ebook::EpubGenerator end def generate_chapter(chapter) - StringIO.new render_template('chapter', chapter) + StringIO.new render_template('chapter', OpenStruct.new( chapter: chapter, rendered: self.render_chapter(chapter))) + end + + def self.render_chapter(chapter) + body = chapter.body + body.lstrip! + body = body.split "\n" + + # This is fucking bad, this gets rid of the redundant title - this should be fixed upstairs, + # in the actual generation of the Markdown. + if body.length >= 2 && body[0] == chapter.title && !body[1].empty? && body[1][0] == '=' + body = body[2..] + end + + self.markdown.render body.join("\n") + end + + def self.markdown + @@markdown ||= + Redcarpet::Markdown.new(Redcarpet::Render::HTML, autolink: true, tables: true) end end diff --git a/app/lib/ebook/templates/chapter.html.slim b/app/lib/ebook/templates/chapter.html.slim index 797415f..997c90b 100644 --- a/app/lib/ebook/templates/chapter.html.slim +++ b/app/lib/ebook/templates/chapter.html.slim @@ -3,8 +3,8 @@ html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" head meta http-equiv="Content-Type" content="text/html; charset=UTF-8" link rel="stylesheet" href="styles.css" - title= title + title= chapter.title body - h1= title + h1= chapter.title .calibre2#content - == StoryRenderer.render_chapter(self) \ No newline at end of file + == rendered \ No newline at end of file diff --git a/app/lib/story_renderer.rb b/app/lib/story_renderer.rb index ede5955..644ffe3 100644 --- a/app/lib/story_renderer.rb +++ b/app/lib/story_renderer.rb @@ -6,7 +6,7 @@ class StoryRenderer @story = story end - def text + def txt markdown = Redcarpet::Markdown.new(Redcarpet::Render::StripDown) separator = '//-------------------------------------------------------//' @@ -31,5 +31,6 @@ class StoryRenderer end def epub + Ebook::EpubGenerator.new(@story).generate end end diff --git a/app/views/stories/show.html.slim b/app/views/stories/show.html.slim index c7a5cc0..887741d 100644 --- a/app/views/stories/show.html.slim +++ b/app/views/stories/show.html.slim @@ -42,6 +42,8 @@ div.story span Download: = link_to story_download_path(@story, fmt: 'txt') do img src="/img/icons/txt32.png" alt="text" title="Download condensed text format" + = link_to story_download_path(@story, fmt: 'epub') do + img src="/img/icons/epub32.png" alt="ePUB" title="Download ePUB format" .chapterlist h3= pluralize(@chapters.count, 'Chapter') + ':' diff --git a/config/application.rb b/config/application.rb index 2e76147..78d9cf4 100644 --- a/config/application.rb +++ b/config/application.rb @@ -33,6 +33,7 @@ Bundler.require(*Rails.groups) # # config.time_zone = "Central Time (US & Canada)" # config.eager_load_paths << Rails.root.join("extras") +module Foalfetch; end class Foalfetch::Application < Rails::Application # Initialize configuration defaults for originally generated Rails version. config.load_defaults 7.0