From fd42a3f17394ae73711133b3ad2f69b5e626fad4 Mon Sep 17 00:00:00 2001 From: david Date: Wed, 24 Jul 2024 01:48:27 +0200 Subject: [PATCH] backups --- .forgejo/workflows/ci_cd.yml | 2 +- .gitignore | 3 +- app/controllers/admin/backups_controller.rb | 8 ++ app/models/admin/backup.rb | 89 +++++++++++++++++++ app/views/home/show.html.erb | 4 + config/routes.rb | 6 +- .../admin/backups_controller_test.rb | 8 ++ test/system/admin/backups_test.rb | 7 ++ 8 files changed, 123 insertions(+), 4 deletions(-) create mode 100644 app/controllers/admin/backups_controller.rb create mode 100644 app/models/admin/backup.rb create mode 100644 test/controllers/admin/backups_controller_test.rb create mode 100644 test/system/admin/backups_test.rb diff --git a/.forgejo/workflows/ci_cd.yml b/.forgejo/workflows/ci_cd.yml index 0005afc..0f17daa 100644 --- a/.forgejo/workflows/ci_cd.yml +++ b/.forgejo/workflows/ci_cd.yml @@ -29,7 +29,7 @@ jobs: - run: mv /app/node_modules . - run: bundle exec rails test - system_test: + system-test: runs-on: docker name: Run system tests container: code.hohl.cloud/jwa11y/a11yist:ci diff --git a/.gitignore b/.gitignore index c1c4704..f03a098 100644 --- a/.gitignore +++ b/.gitignore @@ -40,4 +40,5 @@ /node_modules /.irbrc_history .~lock* -.build_version \ No newline at end of file +.build_version +/core* \ No newline at end of file diff --git a/app/controllers/admin/backups_controller.rb b/app/controllers/admin/backups_controller.rb new file mode 100644 index 0000000..65dcf87 --- /dev/null +++ b/app/controllers/admin/backups_controller.rb @@ -0,0 +1,8 @@ +module Admin + class BackupsController < ApplicationController + # GET /admin/backups/1 + def show + send_file Backup.db_xlsx, filename: 'backup.xlsx', disposition: :attachment + end + end +end diff --git a/app/models/admin/backup.rb b/app/models/admin/backup.rb new file mode 100644 index 0000000..40d6bbb --- /dev/null +++ b/app/models/admin/backup.rb @@ -0,0 +1,89 @@ +module Admin + class Backup + class << self + def zip + create_records_xlsx + + ZipFileGenerator.new(Rails.root.join('storage')).write + end + + def db_xlsx + xlsx = Axlsx::Package.new + workbook = xlsx.workbook + ActiveRecord::Base.connection.tables.each do |table| + klass = table.classify.safe_constantize + next unless klass + + workbook.add_worksheet(name: table) do |sheet| + sheet << klass.attribute_names + klass.find_each do |record| + sheet << record.attributes.values + end + end + end + path = Rails.root.join('storage/data.xls') + xlsx.serialize(path) + path + end + + private + + def file_path(name) + Rails.root.join('storage', name) + end + end + end + + # This is a simple example which uses rubyzip to + # recursively generate a zip file from the contents of + # a specified directory. The directory itself is not + # included in the archive, rather just its contents. + # + # Usage: + # directory_to_zip = "/tmp/input" + # output_file = "/tmp/out.zip" + # zf = ZipFileGenerator.new(directory_to_zip, output_file) + # zf.write() + class ZipFileGenerator + # Initialize with the directory to zip and the location of the output archive. + def initialize(input_dir) + @input_dir = input_dir + end + + # Zip the input directory. + def write + entries = Dir.entries(@input_dir) - %w[. ..] + path = Rails.root.join('tmp', Time.now.to_i.to_s) + ::Zip::File.open(path, create: true) do |zipfile| + write_entries entries, '', zipfile + end + path + end + + private + + # A helper method to make the recursion work. + def write_entries(entries, path, zipfile) + entries.each do |e| + zipfile_path = path == '' ? e : File.join(path, e) + disk_file_path = File.join(@input_dir, zipfile_path) + + if File.directory? disk_file_path + recursively_deflate_directory(disk_file_path, zipfile, zipfile_path) + else + put_into_archive(disk_file_path, zipfile, zipfile_path) + end + end + end + + def recursively_deflate_directory(disk_file_path, zipfile, zipfile_path) + zipfile.mkdir zipfile_path + subdir = Dir.entries(disk_file_path) - %w[. ..] + write_entries subdir, zipfile_path, zipfile + end + + def put_into_archive(disk_file_path, zipfile, zipfile_path) + zipfile.add(zipfile_path, disk_file_path) + end + end +end diff --git a/app/views/home/show.html.erb b/app/views/home/show.html.erb index 6f689df..b9e3e6a 100644 --- a/app/views/home/show.html.erb +++ b/app/views/home/show.html.erb @@ -17,3 +17,7 @@ <%= Check.count %> <%= link_to Check.model_name.human(count: Check.count), :checks %>

+ +

+ <%= link_to "Backup herunterladen", admin_backup_url, class: "btn btn-secondary", data: { turbo_prefetch: false, frame: "_top", turbo: false } %> +

\ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index bfd0427..92e3784 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,5 +1,9 @@ # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html Rails.application.routes.draw do + namespace :admin do + get "backup", to: "backups#show", as: :backup + end + resources :reports resources :checklists resources :checks @@ -8,8 +12,6 @@ Rails.application.routes.draw do resources :success_criteria resources :elements - get 'home/show', as: :home - # Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500. # Can be used by load balancers and uptime monitors to verify that the app is live. get 'up' => 'rails/health#show', as: :rails_health_check diff --git a/test/controllers/admin/backups_controller_test.rb b/test/controllers/admin/backups_controller_test.rb new file mode 100644 index 0000000..7e5ef21 --- /dev/null +++ b/test/controllers/admin/backups_controller_test.rb @@ -0,0 +1,8 @@ +require 'test_helper' + +class Admin::BackupsControllerTest < ActionDispatch::IntegrationTest + test 'should show admin_backup' do + get admin_backup_url(@admin_backup) + assert_response :success + end +end diff --git a/test/system/admin/backups_test.rb b/test/system/admin/backups_test.rb new file mode 100644 index 0000000..3cc9dd1 --- /dev/null +++ b/test/system/admin/backups_test.rb @@ -0,0 +1,7 @@ +require 'application_system_test_case' + +class Admin::BackupsTest < ApplicationSystemTestCase + test 'should create backup' do + visit admin_backup_url + end +end