omg_image 0.0.5 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +23 -6
- data/app/helpers/omg_image/application_helper.rb +0 -68
- data/lib/omg_image.rb +3 -0
- data/lib/omg_image/os.rb +17 -0
- data/lib/omg_image/processor.rb +99 -0
- data/lib/omg_image/renderer.rb +2 -2
- data/lib/omg_image/shell.rb +20 -0
- data/lib/omg_image/version.rb +1 -1
- metadata +5 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: b2468443fcac5db5037221c0d614ed9d16fa51ac58e281c5c3ec1aebfd2e3277
         | 
| 4 | 
            +
              data.tar.gz: 067c8727a59676100fe820f44eddf256f1bf8882726f100764d43d43ca06e911
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 7fa3d8b5b59401f968f2d25017ecb67074750347d8519d84dc17b2070085ac8dd9423627b94e255986ae787376b6354a15c4becda1e4d1db699d966012fde3ef
         | 
| 7 | 
            +
              data.tar.gz: c9da19ea224ddda303bfd09f1e04e4f16893f8aac6b8ea935004802c4c8736129ddfd050399379ef72b489d99fea37899611cf3548a6c6c78c769222c735b57d
         | 
    
        data/README.md
    CHANGED
    
    | @@ -1,10 +1,15 @@ | |
| 1 | 
            -
            #  | 
| 2 | 
            -
             | 
| 1 | 
            +
            # omg_image
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            Generate preview images on the fly for your HTML snippets.
         | 
| 3 4 |  | 
| 4 5 | 
             
            ## Usage
         | 
| 5 | 
            -
             | 
| 6 | 
            +
             | 
| 7 | 
            +
            ## Requirements
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            - Google chrome (headless)
         | 
| 6 10 |  | 
| 7 11 | 
             
            ## Installation
         | 
| 12 | 
            +
             | 
| 8 13 | 
             
            Add this line to your application's Gemfile:
         | 
| 9 14 |  | 
| 10 15 | 
             
            ```ruby
         | 
| @@ -21,19 +26,31 @@ Or install it yourself as: | |
| 21 26 | 
             
            $ gem install omg_image
         | 
| 22 27 | 
             
            ```
         | 
| 23 28 |  | 
| 29 | 
            +
            ## Google Chrome Installation
         | 
| 30 | 
            +
             | 
| 31 | 
            +
            - sudo apt install gdebi-core
         | 
| 32 | 
            +
            - wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
         | 
| 33 | 
            +
            - sudo gdebi google-chrome-stable_current_amd64.deb
         | 
| 34 | 
            +
            - verify chrome is installed `google-chrome --version`
         | 
| 35 | 
            +
             | 
| 24 36 | 
             
            ## Development
         | 
| 25 37 |  | 
| 26 | 
            -
            - install chrome headless | 
| 38 | 
            +
            - install chrome headless
         | 
| 27 39 | 
             
            - add to `/etc/hosts` new host `127.0.0.0     site.com`
         | 
| 28 40 | 
             
            - in `puma.rb` put `workers ENV.fetch("WEB_CONCURRENCY") { 3 }` (required because screenshot is made from another request)
         | 
| 29 | 
            -
            - | 
| 41 | 
            +
            -
         | 
| 42 | 
            +
             | 
| 43 | 
            +
            ## More about Chrome
         | 
| 44 | 
            +
             | 
| 45 | 
            +
            - https://linuxize.com/post/how-to-install-google-chrome-web-browser-on-ubuntu-18-04/
         | 
| 30 46 |  | 
| 31 47 | 
             
            ## Issues
         | 
| 32 48 |  | 
| 33 49 | 
             
            - if you process too many requests and because of timeouts dead processes may appear. To kill them `parents_of_dead_kids=$(ps -ef | grep [d]efunct | awk '{print $3}' | sort | uniq | egrep -v '^1$'); echo "$parents_of_dead_kids" | xargs kill`
         | 
| 34 50 |  | 
| 35 51 | 
             
            ## Contributing
         | 
| 36 | 
            -
             | 
| 52 | 
            +
             | 
| 53 | 
            +
            You are welcome to contribute.
         | 
| 37 54 |  | 
| 38 55 | 
             
            ## License
         | 
| 39 56 | 
             
            The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
         | 
| @@ -6,73 +6,5 @@ require 'open4' | |
| 6 6 | 
             
            module OmgImage
         | 
| 7 7 | 
             
              module ApplicationHelper
         | 
| 8 8 | 
             
                include OmgHelper
         | 
| 9 | 
            -
             | 
| 10 | 
            -
                def omg_image_preview(template, options)
         | 
| 11 | 
            -
                  options        ||= {}
         | 
| 12 | 
            -
                  options[:size] ||= '800,400'
         | 
| 13 | 
            -
                  options[:key]  ||= options.to_s
         | 
| 14 | 
            -
             | 
| 15 | 
            -
                  image = OmgImage::Image.find_by(key: options[:key])
         | 
| 16 | 
            -
                  if image && !image.file.attached?
         | 
| 17 | 
            -
                    image.destroy
         | 
| 18 | 
            -
                    image = nil
         | 
| 19 | 
            -
                  end
         | 
| 20 | 
            -
             | 
| 21 | 
            -
                  file = image&.file || create_screenshot(template, options)
         | 
| 22 | 
            -
             | 
| 23 | 
            -
                  url_for(file) if file
         | 
| 24 | 
            -
                end
         | 
| 25 | 
            -
             | 
| 26 | 
            -
                private
         | 
| 27 | 
            -
             | 
| 28 | 
            -
                def create_screenshot(template, options)
         | 
| 29 | 
            -
                  begin
         | 
| 30 | 
            -
                    start = Time.now
         | 
| 31 | 
            -
                    body  = OmgImage::Renderer.render(template, locals: options)
         | 
| 32 | 
            -
                    log_smt "  to_html: #{(Time.now - start).round(2)}"
         | 
| 33 | 
            -
             | 
| 34 | 
            -
                    input = BetterTempfile.new("input.html")
         | 
| 35 | 
            -
                    input.write(body)
         | 
| 36 | 
            -
                    input.flush
         | 
| 37 | 
            -
             | 
| 38 | 
            -
                    output = BetterTempfile.new("image.png")
         | 
| 39 | 
            -
             | 
| 40 | 
            -
                    cli_options = { file: output, size: options[:size], path: input.path }
         | 
| 41 | 
            -
                    command = build_chrome_command(cli_options)
         | 
| 42 | 
            -
                    log_smt "  => #{command}"
         | 
| 43 | 
            -
             | 
| 44 | 
            -
                    start = Time.now
         | 
| 45 | 
            -
                    begin
         | 
| 46 | 
            -
                      process = open4.spawn(command, timeout: 10)
         | 
| 47 | 
            -
                    rescue Timeout::Error
         | 
| 48 | 
            -
                      Process.kill('KILL', process.pid) rescue nil
         | 
| 49 | 
            -
                      log_smt "omg error: please retry. options: #{options}"
         | 
| 50 | 
            -
                      return nil
         | 
| 51 | 
            -
                    end
         | 
| 52 | 
            -
                    log_smt "  to_image: #{(Time.now - start).round(2)}"
         | 
| 53 | 
            -
             | 
| 54 | 
            -
                    image   = OmgImage::Image.find_by(key: options[:key])
         | 
| 55 | 
            -
                    image ||= OmgImage::Image.new(key: options[:key])
         | 
| 56 | 
            -
                    if !image.file.attached?
         | 
| 57 | 
            -
                      image.file.attach(io: File.open(output.path), filename: "image.png", content_type: "image/png")
         | 
| 58 | 
            -
                      image.save!
         | 
| 59 | 
            -
                    end
         | 
| 60 | 
            -
             | 
| 61 | 
            -
                    image.file
         | 
| 62 | 
            -
                  ensure
         | 
| 63 | 
            -
                    output&.close!
         | 
| 64 | 
            -
                    input&.close!
         | 
| 65 | 
            -
                  end
         | 
| 66 | 
            -
                end
         | 
| 67 | 
            -
             | 
| 68 | 
            -
                def build_chrome_command(options)
         | 
| 69 | 
            -
                  size_opts = options[:size] == :auto ? nil : "--window-size=#{options[:size]}"
         | 
| 70 | 
            -
                  "google-chrome --headless --disable-gpu --no-sandbox --ignore-certificate-errors --screenshot=#{options[:file].path} #{size_opts} \"file://#{options[:path]}\""
         | 
| 71 | 
            -
                end
         | 
| 72 | 
            -
             | 
| 73 | 
            -
                def log_smt(str)
         | 
| 74 | 
            -
                  Rails.logger.debug(str)
         | 
| 75 | 
            -
                end
         | 
| 76 | 
            -
             | 
| 77 9 | 
             
              end
         | 
| 78 10 | 
             
            end
         | 
    
        data/lib/omg_image.rb
    CHANGED
    
    
    
        data/lib/omg_image/os.rb
    ADDED
    
    | @@ -0,0 +1,17 @@ | |
| 1 | 
            +
            module OS
         | 
| 2 | 
            +
              def OS.windows?
         | 
| 3 | 
            +
                (/cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM) != nil
         | 
| 4 | 
            +
              end
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              def OS.mac?
         | 
| 7 | 
            +
               (/darwin/ =~ RUBY_PLATFORM) != nil
         | 
| 8 | 
            +
              end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              def OS.unix?
         | 
| 11 | 
            +
                !OS.windows?
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              def OS.linux?
         | 
| 15 | 
            +
                OS.unix? and not OS.mac?
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
            end
         | 
| @@ -0,0 +1,99 @@ | |
| 1 | 
            +
            module OmgImage
         | 
| 2 | 
            +
              class Processor
         | 
| 3 | 
            +
                attr_reader :template, :options
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                def initialize(template, options)
         | 
| 6 | 
            +
                  template.downcase!
         | 
| 7 | 
            +
                  options        ||= {}
         | 
| 8 | 
            +
                  options[:size] ||= '800,400'
         | 
| 9 | 
            +
                  options[:key]  ||= options.to_s
         | 
| 10 | 
            +
                  template         = "#{template}.html.erb" unless template.ends_with?(".html.erb")
         | 
| 11 | 
            +
                  @template        = template
         | 
| 12 | 
            +
                  @options         = options
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                def cached_or_new(regenerate: false)
         | 
| 16 | 
            +
                  reset_cache if regenerate
         | 
| 17 | 
            +
                  cached&.file || generate&.file
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                def generate(cache: true)
         | 
| 21 | 
            +
                  output = create_screenshot
         | 
| 22 | 
            +
                  if cache
         | 
| 23 | 
            +
                    image = save_to_cache(output)
         | 
| 24 | 
            +
                    output&.close
         | 
| 25 | 
            +
                    image
         | 
| 26 | 
            +
                  else
         | 
| 27 | 
            +
                    output
         | 
| 28 | 
            +
                  end
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                def with_screenshot(&block)
         | 
| 32 | 
            +
                  create_screenshot(&block)
         | 
| 33 | 
            +
                end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                private
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                def create_screenshot
         | 
| 38 | 
            +
                  begin
         | 
| 39 | 
            +
                    start = Time.now
         | 
| 40 | 
            +
                    body  = OmgImage::Renderer.render(template, locals: options)
         | 
| 41 | 
            +
                    log_smt "  to_html: #{(Time.now - start).round(2)}"
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                    input = BetterTempfile.new("input.html")
         | 
| 44 | 
            +
                    input.write(body)
         | 
| 45 | 
            +
                    input.flush
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                    output = BetterTempfile.new("image.png")
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                    command = Shell.command({ file: output, size: options[:size], path: input.path })
         | 
| 50 | 
            +
                    log_smt "  => #{command}"
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                    start = Time.now
         | 
| 53 | 
            +
                    begin
         | 
| 54 | 
            +
                      process = open4.spawn(command, timeout: 10)
         | 
| 55 | 
            +
                    rescue Timeout::Error
         | 
| 56 | 
            +
                      Process.kill('KILL', process.pid) rescue nil
         | 
| 57 | 
            +
                      log_smt "omg error: please retry. options: #{options}"
         | 
| 58 | 
            +
                      return nil
         | 
| 59 | 
            +
                    end
         | 
| 60 | 
            +
                    log_smt "  to_image: #{(Time.now - start).round(2)}"
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                    yield(output) if block_given?
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                    output
         | 
| 65 | 
            +
                  ensure
         | 
| 66 | 
            +
                    #output&.close!
         | 
| 67 | 
            +
                    input&.close!
         | 
| 68 | 
            +
                  end
         | 
| 69 | 
            +
                end
         | 
| 70 | 
            +
             | 
| 71 | 
            +
                def log_smt(str)
         | 
| 72 | 
            +
                  Rails.logger.debug(str)
         | 
| 73 | 
            +
                end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                def reset_cache
         | 
| 76 | 
            +
                   OmgImage::Image.where(key: options[:key]).destroy_all
         | 
| 77 | 
            +
                end
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                def cached
         | 
| 80 | 
            +
                  image = OmgImage::Image.find_by(key: options[:key])
         | 
| 81 | 
            +
                  if image && !image.file.attached?
         | 
| 82 | 
            +
                    image.destroy
         | 
| 83 | 
            +
                    image = nil
         | 
| 84 | 
            +
                  end
         | 
| 85 | 
            +
                  image
         | 
| 86 | 
            +
                end
         | 
| 87 | 
            +
             | 
| 88 | 
            +
                def save_to_cache(output)
         | 
| 89 | 
            +
                  image   = OmgImage::Image.find_by(key: options[:key])
         | 
| 90 | 
            +
                  image ||= OmgImage::Image.new(key: options[:key])
         | 
| 91 | 
            +
                  if !image.file.attached?
         | 
| 92 | 
            +
                    image.file.attach(io: File.open(output.path), filename: "image.png", content_type: "image/png")
         | 
| 93 | 
            +
                    image.save!
         | 
| 94 | 
            +
                  end
         | 
| 95 | 
            +
                  image
         | 
| 96 | 
            +
                end
         | 
| 97 | 
            +
             | 
| 98 | 
            +
              end
         | 
| 99 | 
            +
            end
         | 
    
        data/lib/omg_image/renderer.rb
    CHANGED
    
    | @@ -2,8 +2,8 @@ module OmgImage | |
| 2 2 | 
             
              class Renderer
         | 
| 3 3 | 
             
                def Renderer.render(template, layout: nil, locals: {})
         | 
| 4 4 | 
             
                  ::ApplicationController.render(
         | 
| 5 | 
            -
                    file: "/#{Rails.root}/app/omg/#{template}", | 
| 6 | 
            -
                    layout: layout, | 
| 5 | 
            +
                    file: "/#{Rails.root}/app/omg/#{template}",
         | 
| 6 | 
            +
                    layout: layout,
         | 
| 7 7 | 
             
                    locals: locals
         | 
| 8 8 | 
             
                  )
         | 
| 9 9 | 
             
                end
         | 
| @@ -0,0 +1,20 @@ | |
| 1 | 
            +
            module OmgImage
         | 
| 2 | 
            +
              class Shell
         | 
| 3 | 
            +
                def Shell.command(options)
         | 
| 4 | 
            +
                  size_opts = options[:size] == :auto ? nil : "--window-size=#{options[:size]}"
         | 
| 5 | 
            +
                  "#{chrome} --headless --disable-gpu --no-sandbox --ignore-certificate-errors --screenshot=#{options[:file].path} #{size_opts} \"file://#{options[:path]}\""
         | 
| 6 | 
            +
                end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                private
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                def self.chrome
         | 
| 11 | 
            +
                  if OS.windows?
         | 
| 12 | 
            +
                    "chrome"
         | 
| 13 | 
            +
                  elsif OS.mac?
         | 
| 14 | 
            +
                    "\"/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome\""
         | 
| 15 | 
            +
                  else
         | 
| 16 | 
            +
                    "google-chrome"
         | 
| 17 | 
            +
                  end
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
            end
         | 
    
        data/lib/omg_image/version.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: omg_image
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.0. | 
| 4 | 
            +
              version: 0.0.6
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Igor Kasyanchuk
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2018-11- | 
| 11 | 
            +
            date: 2018-11-13 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: rails
         | 
| @@ -123,7 +123,10 @@ files: | |
| 123 123 | 
             
            - lib/generators/templates/db/migrate/20180928082949_create_omg_image_images.rb
         | 
| 124 124 | 
             
            - lib/omg_image.rb
         | 
| 125 125 | 
             
            - lib/omg_image/engine.rb
         | 
| 126 | 
            +
            - lib/omg_image/os.rb
         | 
| 127 | 
            +
            - lib/omg_image/processor.rb
         | 
| 126 128 | 
             
            - lib/omg_image/renderer.rb
         | 
| 129 | 
            +
            - lib/omg_image/shell.rb
         | 
| 127 130 | 
             
            - lib/omg_image/version.rb
         | 
| 128 131 | 
             
            homepage: https://github.com/igorkasyanchuk/omg_image
         | 
| 129 132 | 
             
            licenses:
         |