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