diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000000000000000000000000000000000000..ad63f70273b447516de6a05e6cb41ce3b8283663
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,7 @@
+.git
+log/
+tmp/
+public/system/
+public/assets/
+vendor/
+shared/
diff --git a/.env.dev b/.env.dev
new file mode 100644
index 0000000000000000000000000000000000000000..75723cce1ef9a38e5340957170cf567c4b46346f
--- /dev/null
+++ b/.env.dev
@@ -0,0 +1,41 @@
+# '.env' file example for local development.
+# Copy this file to a file named '.env' and make changes there.
+# The final '.env' file should not be commited to version control.
+# Set the *_PASSWORD variables with actual passwords.
+# 'host.docker.internal' resolves to the IP of the host machine inside the docker network.
+
+PORTALMEC_API_URL=localhost
+
+PORTALMEC_DB_HOST=host.docker.internal
+PORTALMEC_DB_POOL=25
+PORTALMEC_DB_NAME=portalmec
+PORTALMEC_DB_USERNAME=portalmec
+PORTALMEC_DB_PASSWORD=
+
+PORTALMEC_DSPACE_LOGIN=admin@mecdb3.c3sl.ufpr.br
+PORTALMEC_DSPACE_PASSWORD=
+PORTALMEC_DSPACE_PORT=8443
+PORTALMEC_DSPACE_HOST=mecdb4.c3sl.ufpr.br
+
+PORTALMEC_ELASTICSEARCH_PORT=9200
+PORTALMEC_ELASTICSEARCH_HOST=host.docker.internal
+PORTALMEC_ELASTICSEARCH_LOGIN=elastic
+PORTALMEC_ELASTICSEARCH_PASSWORD=
+PORTALMEC_ELASTICSEARCH_INDEX_PREFIX=
+
+MEMCACHE_SERVERS=localhost
+ACTION_MAILER_HOST=api.portalmectest.c3sl.ufpr.br
+SMTP_ADDRESS=urquell.c3sl.ufpr.br
+SMTP_PORT=587
+GITLAB_PORTALMEC_PRIVATE_TOKEN=
+
+RAILS_SERVE_STATIC_FILES=FALSE
+RAILS_ENV=development
+PORT=3000
+WEB_CONCURRENCY=8 
+RAILS_MAX_THREADS=8 
+
+REDIS_HOST=redis
+
+GOOGLE_KEY=
+GOOGLE_SECRET=
diff --git a/.gitignore b/.gitignore
index 5767d2bf65adf0dc83b3068f876ec7a1f4384a70..62cdd175ab578c5c6805ac4acfc91d8f89e36b80 100644
--- a/.gitignore
+++ b/.gitignore
@@ -39,3 +39,5 @@ autocomplete-server.service
 # ignore configs
 /config/database.yml
 /config/sidekiq.yml
+.env
+.env.prod
diff --git a/Dockerfile b/Dockerfile
index 0f5a273dd3aff2a1278261d9d2f99ffdbf727d0c..bcb62297504ce90e95fa7d63dd9b198929633097 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,13 +1,32 @@
-FROM ruby:2.2.0
-RUN apt-get update -qq && apt-get install -y build-essential nodejs
+# syntax=docker/dockerfile:1
 
-RUN mkdir /app
+FROM ruby:3.1.0-alpine
 
-WORKDIR /tmp
-COPY Gemfile Gemfile
-COPY Gemfile.lock Gemfile.lock
-RUN bundle install -j 3
+ENV BUNDLER_VERSION=2.3.26
+
+RUN gem install bundler -v 2.3.26
 
 WORKDIR /app
 
-CMD ["rails", "server", "-b", "0.0.0.0"]
+COPY Gemfile Gemfile.lock ./
+
+RUN apk add --update --no-cache \
+        build-base \
+        curl-dev \
+        shared-mime-info \
+        postgresql-dev \
+        file \
+        imagemagick-dev \
+        nodejs-current \
+        libarchive \
+        git
+
+# Prevent libxml2 and libxslt conflicts
+RUN bundle config build.nokogiri --use-system-libraries
+
+# Only install if Gemfile not satisfied
+RUN bundle check || bundle install
+
+COPY . ./
+
+ENTRYPOINT ["./entrypoints/docker-entrypoint.sh"]
diff --git a/Gemfile b/Gemfile
index b60365f7d8520effe74d2f1f2ffa1f0f15a7de52..bb639a56af932a488291be40fbbde06ba813d90a 100644
--- a/Gemfile
+++ b/Gemfile
@@ -185,4 +185,6 @@ gem 'elasticsearch', '~> 8.6'
 gem 'multipart-post', '~> 2.0'
 
 gem 'faraday-multipart', '~> 1.0', '>= 1.0.4'
+gem 'tzinfo-data'
+
 
diff --git a/app/models/collection.rb b/app/models/collection.rb
index b88f3f1b9e9372652702becf86334b376dedb825..5a05ed7b1eb011a6edb784bcf23ce31e83846eb1 100644
--- a/app/models/collection.rb
+++ b/app/models/collection.rb
@@ -73,7 +73,7 @@ class Collection < ApplicationRecord
 
   scope :from_user, ->(user) { where(owner: user) }
 
-  searchkick language: 'brazilian', match: :word_start, searchable: [:name, :description, :author], callbacks: :async, index_prefix: Socket.gethostname.downcase, merge_mappings: true, mappings: {
+  searchkick language: 'brazilian', match: :word_start, searchable: [:name, :description, :author], callbacks: :async, merge_mappings: true, mappings: {
     "properties": {
       "created_at": {
         "type": "date"
diff --git a/app/models/learning_object.rb b/app/models/learning_object.rb
index 0ba7335aa6e8cff9e97715229be9a12e210fcd55..5273abbd61509ddefe67f55afd5868e95709c944 100644
--- a/app/models/learning_object.rb
+++ b/app/models/learning_object.rb
@@ -99,7 +99,7 @@ class LearningObject < ApplicationRecord
   default_scope { includes(:object_type, :attachment, :attachments) }
   scope :missing_thumbnail, ->() { where(thumbnail_file_name: nil) }
 
-  searchkick language: 'brazilian', match: :word_start, searchable: [:name, :description, :author, :object_type, :tags, :subjects, :educational_stages, :languages], callbacks: :async, index_prefix: Socket.gethostname.downcase, merge_mappings: true, mappings: {
+  searchkick language: 'brazilian', match: :word_start, searchable: [:name, :description, :author, :object_type, :tags, :subjects, :educational_stages, :languages], callbacks: :async, merge_mappings: true, mappings: {
     "properties": {
       "published_at": {
         "type": "date"
diff --git a/app/models/user.rb b/app/models/user.rb
index f01650244285960f9e5635aab7a35db1a2cd1d68..e2c2ec53d1fa0a77af31a11b282549d468e502f9 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -164,7 +164,7 @@ class User < ApplicationRecord
 
   enum state: { active: 0, blocked: 1, banished: 2}
 
-  searchkick language: 'brazilian', match: :word_start, searchable: [:name], callbacks: :async, index_prefix: Socket.gethostname.downcase
+  searchkick language: 'brazilian', match: :word_start, searchable: [:name], callbacks: :async
 
   acts_as_paranoid
 
diff --git a/config/application.rb b/config/application.rb
index 552d3f5ce92635b6964b3a4a67b6b29456d2e7b4..4751209cd33b95ee9706afa6dd991798f54890d0 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -72,7 +72,7 @@ module Portalmec
     #   end
     # end
 
-    config.middleware.use Rack::Cors do
+    config.middleware.insert_before 0, Rack::Cors do
       allow do
         origins '*'
         resource '*',
@@ -101,6 +101,11 @@ module Portalmec
     config.middleware.use ActionDispatch::Cookies
     config.middleware.use ActionDispatch::Session::CookieStore
 
+    # host authorization
+    if ENV.key?("PORTALMEC_API_URL")
+      config.hosts << ENV["PORTALMEC_API_URL"]
+    end
 
+    config.hosts << "localhost"
   end
 end
diff --git a/config/database.yml b/config/database.yml
index 20ae345b07dcaf8cdb281acd0c434e0c99bb7777..eec5db4fafd799df870084e9c5ff70c8ac6a1796 100644
--- a/config/database.yml
+++ b/config/database.yml
@@ -1,24 +1,4 @@
-# default: &defaults
-#   adapter: postgresql
-#   encoding: unicode
-
-development:
-  adapter: postgresql
-  encoding: unicode
-  database: portalmecapi
-  username: postgres
-  password: 123mudar
-  host: localhost
-
-test:
-  adapter: postgresql
-  encoding: unicode
-  database: portalmecapi
-  username: postgres
-  password: 123mudar
-  host: localhost
-
-production:
+default: &default
   adapter: postgresql
   encoding: unicode
   timeout: 30000
@@ -27,4 +7,14 @@ production:
   database: <%= ENV['PORTALMEC_DB_NAME'] %>
   username: <%= ENV['PORTALMEC_DB_USERNAME'] %>
   password: <%= ENV['PORTALMEC_DB_PASSWORD'] %>
+
+development:
+  <<: *default
+
+test:
+  <<: *default
+
+production:
+  <<: *default
   reaping_frequency: 30
+
diff --git a/config/initializers/eager_load.rb b/config/initializers/eager_load.rb
index ef15c6e4573b27da6266b2b263d057dd9db31f5c..00abea411784a180a3e9d4b2b9c08c60e1d68d77 100644
--- a/config/initializers/eager_load.rb
+++ b/config/initializers/eager_load.rb
@@ -17,4 +17,5 @@
 # You should have received a copy of the GNU Affero General Public License
 # along with portalmec.  If not, see <http://www.gnu.org/licenses/>.
 
-Rails.application.eager_load! unless Rails.env.test?
+# Rails.application.eager_load! unless Rails.env.test?
+
diff --git a/config/initializers/elasticsearch.rb b/config/initializers/elasticsearch.rb
index 9a3b628ece9d05b53e0057027bb5652e122d92df..fef4adf01a3de0f4c99e50272e74a6cb1909f4ba 100644
--- a/config/initializers/elasticsearch.rb
+++ b/config/initializers/elasticsearch.rb
@@ -16,38 +16,28 @@
 #
 # You should have received a copy of the GNU Affero General Public License
 # along with portalmec.  If not, see <http://www.gnu.org/licenses/>.
-if Rails.env.production?
-  login = ENV['PORTALMEC_ELASTICSEARCH_LOGIN']
-  pass = ENV['PORTALMEC_ELASTICSEARCH_PASSWORD']
-  host = ENV['PORTALMEC_ELASTICSEARCH_HOST']
-  port = ENV['PORTALMEC_ELASTICSEARCH_PORT']
-  elasticsearch_client = Elasticsearch::Client.new(
-    url: "https://" + login + ":" + pass + "@" + host + ":" + port,
-    transport_options: {
-      request: {
-        timeout: 550
-      },
-      ssl: {
-        verify: false
-      }
-      #,
-      #headers: {
-      #  Authorization: "Basic " + Base64.strict_encode64(login + ":" + pass)
-      #}
+
+login = ENV['PORTALMEC_ELASTICSEARCH_LOGIN'] || "elastic"
+pass = ENV['PORTALMEC_ELASTICSEARCH_PASSWORD'] || ""
+host = ENV['PORTALMEC_ELASTICSEARCH_HOST'] || "elasticsearch"
+port = ENV['PORTALMEC_ELASTICSEARCH_PORT'] || "9200"
+elasticsearch_client = Elasticsearch::Client.new(
+  url: "https://" + login + ":" + pass + "@" + host + ":" + port,
+  transport_options: {
+    request: {
+      timeout: 550
+    },
+    ssl: {
+      verify: false
     }
-  )
-elsif Rails.env.test?
-  elasticsearch_client = Elasticsearch::Client.new(
-    url: 'localhost:9200',
-    transport_options: {request: {timeout: 550}}
-  )
-else
-  elasticsearch_client = Elasticsearch::Client.new(
-    url: 'localhost:9200',
-    transport_options: {request: {timeout: 550}}
-  )
-end
+    #,
+    #headers: {
+    #  Authorization: "Basic " + Base64.strict_encode64(login + ":" + pass)
+    #}
+  }
+)
 
 Searchkick.client = elasticsearch_client
+Searchkick.index_prefix = ENV["PORTALMEC_ELASTICSEARCH_INDEX_PREFIX"]
 #Searchkick.redis = ConnectionPool.new { Redis.new } 
 #Searchkick::ProcessQueueJob.perform_later(class_name: "LearningObject")
diff --git a/docker-compose.yml b/docker-compose.yml
index 107fbac4bc8028096540df9356344d956862b8a5..fd7c58684c63779cf8fbd73fdeb8630c169dd2dc 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -17,22 +17,42 @@
 # You should have received a copy of the GNU Affero General Public License
 # along with portalmec.  If not, see <http://www.gnu.org/licenses/>.
 
-web:
-  build: .
-  volumes:
-    - .:/app
-  ports:
-    - "3000:3000"
-  links:
-    - db
-    - redis
-    - elasticsearch
+version: '3.4'
 
-db:
-  image: postgres
+services:
+  app:
+    build:
+      context: .
+      dockerfile: Dockerfile
+    depends_on:
+      - redis
+    ports:
+      - "3000:3000"
+    volumes:
+      - .:/app
+      - gem_cache:/usr/local/bundle/gems
+    env_file: .env
+    extra_hosts:
+      - "host.docker.internal:host-gateway"
 
-redis:
-  image: redis
+  redis:
+    image: redis:7.0.11-alpine
 
-elasticsearch:
-  image: elasticsearch
\ No newline at end of file
+  sidekiq:
+    build:
+      context: .
+      dockerfile: Dockerfile
+    depends_on:
+      - app
+      - redis
+    volumes:
+      - .:/app
+      - gem_cache:/usr/local/bundle/gems
+    env_file: .env
+    entrypoint: ./entrypoints/sidekiq-entrypoint.sh
+    extra_hosts:
+      - "host.docker.internal:host-gateway"
+
+volumes:
+  gem_cache:
+  db_data:
diff --git a/entrypoints/docker-entrypoint.sh b/entrypoints/docker-entrypoint.sh
new file mode 100755
index 0000000000000000000000000000000000000000..8ec86f8bd5566bfa58c25e58ff3f41c79993cbb3
--- /dev/null
+++ b/entrypoints/docker-entrypoint.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+set -e
+
+# If the container closes unexpectably the lockfile will not be removed and
+# rails will refuse to start. So we remove at the start if it already exists.
+if [ -f tmp/pids/server.pid ]; then
+   rm tmp/pids/server.pid
+fi
+
+exec bundle exec puma -C config/puma.rb
+
diff --git a/entrypoints/init.sql b/entrypoints/init.sql
new file mode 100755
index 0000000000000000000000000000000000000000..bd6b94778ccb5bac4d41ac4cb6a5213e4a9b9f8e
--- /dev/null
+++ b/entrypoints/init.sql
@@ -0,0 +1,2 @@
+CREATE USER portalmec;
+ALTER USER portalmec WITH SUPERUSER;
diff --git a/entrypoints/sidekiq-entrypoint.sh b/entrypoints/sidekiq-entrypoint.sh
new file mode 100755
index 0000000000000000000000000000000000000000..4f81ae2c56a8e1ab41e76ab115f50e508571867c
--- /dev/null
+++ b/entrypoints/sidekiq-entrypoint.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+set -e
+
+if [ -f tmp/pids/server.pid ]; then
+   rm tmp/pids/server.pid
+fi
+
+exec bundle exec sidekiq
+
diff --git a/env b/env
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/lib/log/database_logger.rb b/lib/log/database_logger.rb
index dcb093a6af7513d4d333ca0d6838ea551d663c39..ba37bea425f5d492f29606b1926802a00c12b4db 100644
--- a/lib/log/database_logger.rb
+++ b/lib/log/database_logger.rb
@@ -17,39 +17,37 @@
 # You should have received a copy of the GNU Affero General Public License
 # along with portalmec.  If not, see <http://www.gnu.org/licenses/>.
 
-module Log
-  class DatabaseLogger < Logger
+class DatabaseLogger < Logger
 
-    CREATE = 5
-    SELECT = 6
-    UPDATE = 7
-    DELETE = 8
+  CREATE = 5
+  SELECT = 6
+  UPDATE = 7
+  DELETE = 8
 
-    SEVS = %w(DEBUG INFO WARN ERROR FATAL CREATE SELECT UPDATE DELETE)
-    def format_severity(severity)
-      SEVS[severity] || 'ANY'
-    end
-
-    def create(progname = nil, &block)
-      add(5, nil, progname, &block) unless @db_lvl < 5
-    end
+  SEVS = %w(DEBUG INFO WARN ERROR FATAL CREATE SELECT UPDATE DELETE)
+  def format_severity(severity)
+    SEVS[severity] || 'ANY'
+  end
 
-    def select(progname = nil, &block)
-      add(6, nil, progname, &block) unless @db_lvl < 6
-    end
+  def create(progname = nil, &block)
+    add(5, nil, progname, &block) unless @db_lvl < 5
+  end
 
-    def update(progname = nil, &block)
-      add(7, nil, progname, &block) unless @db_lvl < 7
-    end
+  def select(progname = nil, &block)
+    add(6, nil, progname, &block) unless @db_lvl < 6
+  end
 
-    def delete(progname = nil, &block)
-      add(8, nil, progname, &block) unless @db_lvl < 8
-    end
+  def update(progname = nil, &block)
+    add(7, nil, progname, &block) unless @db_lvl < 7
+  end
 
-    def level=(lvl)
-      @db_lvl = lvl
-      @level = lvl >= 5 ? 1 : lvl
-    end
+  def delete(progname = nil, &block)
+    add(8, nil, progname, &block) unless @db_lvl < 8
+  end
 
+  def level=(lvl)
+    @db_lvl = lvl
+    @level = lvl >= 5 ? 1 : lvl
   end
-end
\ No newline at end of file
+
+end
diff --git a/lib/log/logging.rb b/lib/log/logging.rb
index 80d22c5e8e5ea3a61e6e7451fe03c909ebe54d2e..cff42f876402ef974b40c1a43375e411289f15ae 100644
--- a/lib/log/logging.rb
+++ b/lib/log/logging.rb
@@ -17,27 +17,25 @@
 # You should have received a copy of the GNU Affero General Public License
 # along with portalmec.  If not, see <http://www.gnu.org/licenses/>.
 
-module Log
-  module Logging
-    def logger
-      Logging.logger
-    end
-
-    def self.logger
-      if @logger.nil?
-        @logger = DatabaseLogger.new(nil)
-        @logger.level=-1
-      end
-      @logger
-    end
-
-    def self.logger=(logger)
-      @logger = logger
-    end
+module Logging
+  def logger
+    Logging.logger
+  end
 
-    def self.disable_logging
+  def self.logger
+    if @logger.nil?
       @logger = DatabaseLogger.new(nil)
+      @logger.level=-1
     end
+    @logger
+  end
 
+  def self.logger=(logger)
+    @logger = logger
   end
-end
\ No newline at end of file
+
+  def self.disable_logging
+    @logger = DatabaseLogger.new(nil)
+  end
+
+end
diff --git a/lib/portalmec/sociable_tests.rb b/lib/portalmec/sociable_tests.rb
index d14964562eaf9e40428ae5a5411da66367bc2c09..d5c6d6aa13fdde3c1051feb91162635641684653 100644
--- a/lib/portalmec/sociable_tests.rb
+++ b/lib/portalmec/sociable_tests.rb
@@ -19,6 +19,8 @@
 
 # require 'active_support'
 
+SociableTests = 3 
+
 # module Portalmec::SociableTests
 #   extend ActiveSupport::Testing::Declarative
 
@@ -88,4 +90,4 @@
 #   def sociable_user
 #     users(:john)
 #   end
-# end
\ No newline at end of file
+# end
diff --git a/lib/thumbnail/generatable_strategy.rb b/lib/thumbnail/generatable_strategy.rb
index 185ba4e4653c522e51c72e9bb49f5469c1382e72..7904ece4046bec85b90ac78d92ae2f30f8c1c39e 100644
--- a/lib/thumbnail/generatable_strategy.rb
+++ b/lib/thumbnail/generatable_strategy.rb
@@ -21,25 +21,23 @@ require 'mimemagic'
 
 ##
 # This abstract class representes the interface to generate thumbnails
-module Thumbnail
-  class GeneratableStrategy
+class GeneratableStrategy
 
-    ##
-    # Generate a thumbnail based on the +media+
-    # +media+ needs to be a pointer to a file
-    def generate(media)
-      raise NotImplementedError
-    end
+  ##
+  # Generate a thumbnail based on the +media+
+  # +media+ needs to be a pointer to a file
+  def generate(media)
+    raise NotImplementedError
+  end
 
-    ##
-    # Checks if the strategy can generate a thumbnail of that +media+
-    def can_generate?(media)
-      if File == media.class
-        mime = MimeMagic.by_magic(media)
-        return mime.type.include? yield unless mime.blank?
-      end
-      false
+  ##
+  # Checks if the strategy can generate a thumbnail of that +media+
+  def can_generate?(media)
+    if File == media.class
+      mime = MimeMagic.by_magic(media)
+      return mime.type.include? yield unless mime.blank?
     end
-
+    false
   end
+
 end
diff --git a/lib/thumbnail/strategies/image_thumbnail_generator.rb b/lib/thumbnail/strategies/image_thumbnail_generator.rb
index a5f7533d85e27ef31b1902d66a88a26ee450da6c..a5bad89bbc1589fd7c0886b415dfa36cad1eab68 100644
--- a/lib/thumbnail/strategies/image_thumbnail_generator.rb
+++ b/lib/thumbnail/strategies/image_thumbnail_generator.rb
@@ -17,18 +17,14 @@
 # You should have received a copy of the GNU Affero General Public License
 # along with portalmec.  If not, see <http://www.gnu.org/licenses/>.
 
-module Thumbnail
-  module Strategies
-    class ImageThumbnailGenerator < ::Thumbnail::GeneratableStrategy
+class ImageThumbnailGenerator < ::GeneratableStrategy
 
-      def generate(media)
-        media
-      end
-
-      def can_generate?(media)
-        super { 'image' }
-      end
+  def generate(media)
+    media
+  end
 
-    end
+  def can_generate?(media)
+    super { 'image' }
   end
+
 end
diff --git a/lib/thumbnail/strategies/pdf_thumbnail_generator.rb b/lib/thumbnail/strategies/pdf_thumbnail_generator.rb
index 624bb3e26a3d15bf4dc23ebd3bdf85293b412d97..52b812c520da79954f70a4b73d7b8b57188760d0 100644
--- a/lib/thumbnail/strategies/pdf_thumbnail_generator.rb
+++ b/lib/thumbnail/strategies/pdf_thumbnail_generator.rb
@@ -17,31 +17,27 @@
 # You should have received a copy of the GNU Affero General Public License
 # along with portalmec.  If not, see <http://www.gnu.org/licenses/>.
 
-module Thumbnail
-  module Strategies
-    class PdfThumbnailGenerator < ::Thumbnail::GeneratableStrategy
+class PdfThumbnailGenerator < GeneratableStrategy
 
-      def generate(media)
-        pdf = first_page(media.path)
-        return nil if pdf.blank?
+  def generate(media)
+    pdf = first_page(media.path)
+    return nil if pdf.blank?
 
-        hash = SecureRandom.hex(10)
-        output = "/tmp/#{hash}.png"
-        pdf.write(output)
-        File.open output
-      end
-
-      def can_generate?(media)
-        super { 'pdf' }
-      end
+    hash = SecureRandom.hex(10)
+    output = "/tmp/#{hash}.png"
+    pdf.write(output)
+    File.open output
+  end
 
-      private
+  def can_generate?(media)
+    super { 'pdf' }
+  end
 
-      def first_page(pdf_path)
-        first_page_path = pdf_path + "[0]"
-        Magick::Image.read(first_page_path).first
-      end
+  private
 
-    end
+  def first_page(pdf_path)
+    first_page_path = pdf_path + "[0]"
+    Magick::Image.read(first_page_path).first
   end
+
 end
diff --git a/lib/thumbnail/strategies/url_thumbnail_generator.rb b/lib/thumbnail/strategies/url_thumbnail_generator.rb
index e8a9dbb961e310d4df6408570b8e57ff21710b30..ee7d90d2549e6271627b9662ee990ebd0caf7472 100644
--- a/lib/thumbnail/strategies/url_thumbnail_generator.rb
+++ b/lib/thumbnail/strategies/url_thumbnail_generator.rb
@@ -19,21 +19,17 @@
 
 require 'screencap'
 
-module Thumbnail
-  module Strategies
-    class UrlThumbnailGenerator < ::Thumbnail::GeneratableStrategy
+class UrlThumbnailGenerator < GeneratableStrategy
 
-      def generate(screen)
-        screen.fetch(
-            width: 1024,
-            height: 768
-        )
-      end
-
-      def can_generate?(screen)
-        ::Screencap::Fetcher == screen.class
-      end
+  def generate(screen)
+    screen.fetch(
+        width: 1024,
+        height: 768
+    )
+  end
 
-    end
+  def can_generate?(screen)
+    ::Screencap::Fetcher == screen.class
   end
+
 end
diff --git a/lib/thumbnail/strategies/video_thumbnail_generator.rb b/lib/thumbnail/strategies/video_thumbnail_generator.rb
index 4f0ea0bf2115c6a5208c2d63266e6ddb7d212e8d..529d57e1758ad1b3f97e9a327e8942af6fcbf652 100644
--- a/lib/thumbnail/strategies/video_thumbnail_generator.rb
+++ b/lib/thumbnail/strategies/video_thumbnail_generator.rb
@@ -19,39 +19,35 @@
 
 require 'streamio-ffmpeg'
 
-module Thumbnail
-  module Strategies
-    class VideoThumbnailGenerator < ::Thumbnail::GeneratableStrategy
-
-      def generate(media)
-        movie = build_ffmpeg_movie media.path
-        hash = SecureRandom.hex(10)
-        output = "/tmp/#{hash}.jpg"
-
-        if movie.valid? and !movie.video_codec.nil?
-          frame = (movie.duration * 25/100).floor
-          movie.screenshot(output,
-                           {seek_time: frame, resolution: size},
-                           preserve_aspect_ratio: :width)
-          File.open output
-        else
-          raise "ERROR: Video's thumbnail was not generated. (NULL_CODEC)"
-        end
-      end
-
-      def can_generate?(media)
-        super { 'video' }
-      end
-      private
-
-      def size
-        '530x300'
-      end
-
-      def build_ffmpeg_movie(path)
-        ::FFMPEG::Movie.new(path)
-      end
-
+class VideoThumbnailGenerator < GeneratableStrategy
+
+  def generate(media)
+    movie = build_ffmpeg_movie media.path
+    hash = SecureRandom.hex(10)
+    output = "/tmp/#{hash}.jpg"
+
+    if movie.valid? and !movie.video_codec.nil?
+      frame = (movie.duration * 25/100).floor
+      movie.screenshot(output,
+                       {seek_time: frame, resolution: size},
+                       preserve_aspect_ratio: :width)
+      File.open output
+    else
+      raise "ERROR: Video's thumbnail was not generated. (NULL_CODEC)"
     end
   end
+
+  def can_generate?(media)
+    super { 'video' }
+  end
+  private
+
+  def size
+    '530x300'
+  end
+
+  def build_ffmpeg_movie(path)
+    ::FFMPEG::Movie.new(path)
+  end
+
 end