Skip to content

Commit 52aedeb

Browse files
committed
Add ability to export most recent 500 first iterations
1 parent 56cc13f commit 52aedeb

File tree

9 files changed

+121
-0
lines changed

9 files changed

+121
-0
lines changed

Gemfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ gem "bugsnag"
3333
gem 'aws-sdk-s3'
3434
gem 'image_processing', '~> 1.2'
3535
gem 'rest-client'
36+
gem 'rubyzip', require: false
3637

3738
gem 'bootsnap', '>= 1.1.0', require: false
3839

Gemfile.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,7 @@ DEPENDENCIES
434434
rails (~> 5.2)
435435
rails-controller-testing
436436
rest-client
437+
rubyzip
437438
rugged
438439
sass-rails (~> 5.0)
439440
selenium-webdriver
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
class Admin::Data::ExercisesController < AdminController
2+
def show
3+
@track = Track.find(params[:track_id])
4+
@exercise = @track.exercises.find(params[:id])
5+
6+
@solutions = @exercise.solutions.submitted.order('id DESC').limit(500)
7+
8+
zip_path = ExportSolutionsData.(@solutions)
9+
send_file(zip_path)
10+
end
11+
end
12+
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
class Admin::Data::TracksController < AdminController
2+
def index
3+
@tracks = Track.order('title ASC')
4+
end
5+
6+
def show
7+
@track = Track.find(params[:id])
8+
@exercises = @track.exercises.reorder('slug ASC')
9+
end
10+
end

app/services/export_solutions_data.rb

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
require 'zip'
2+
3+
class ExportSolutionsData
4+
include Mandate
5+
6+
initialize_with :solutions
7+
8+
def call
9+
dir = Rails.root / "tmp" / "export_solutions_data" / "#{Time.now.to_i}-#{SecureRandom.uuid}"
10+
FileUtils.mkdir_p(dir)
11+
12+
solutions.includes(iterations: :files).each.with_index do |solution, idx|
13+
solution_dir = dir / idx.to_s
14+
FileUtils.mkdir(solution_dir)
15+
16+
solution.iterations.first.files.each do |iteration_file|
17+
File.open(solution_dir / iteration_file.filename, "w+") do |file|
18+
file << iteration_file.file_contents
19+
end
20+
end
21+
end
22+
23+
(dir / "archive.zip").tap do |zip_path|
24+
ZipDirectoryRecursively.(dir, zip_path)
25+
end
26+
end
27+
end
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
require 'zip'
2+
3+
# This is a simple example which uses rubyzip to
4+
# recursively generate a zip file from the contents of
5+
# a specified directory. The directory itself is not
6+
# included in the archive, rather just its contents.
7+
#
8+
# Usage:
9+
# directory_to_zip = "/tmp/input"
10+
# output_file = "/tmp/out.zip"
11+
# zf = ZipFileGenerator.new(directory_to_zip, output_file)
12+
# zf.write()
13+
class ZipDirectoryRecursively
14+
include Mandate
15+
16+
initialize_with :input_dir, :output_file
17+
18+
def call
19+
entries = Dir.entries(input_dir) - %w(. ..)
20+
21+
::Zip::File.open(output_file, ::Zip::File::CREATE) do |zipfile|
22+
write_entries entries, '', zipfile
23+
end
24+
end
25+
26+
private
27+
28+
# A helper method to make the recursion work.
29+
def write_entries(entries, path, zipfile)
30+
entries.each do |e|
31+
zipfile_path = path == '' ? e : File.join(path, e)
32+
disk_file_path = File.join(input_dir, zipfile_path)
33+
puts "Deflating #{disk_file_path}"
34+
35+
if File.directory? disk_file_path
36+
recursively_deflate_directory(disk_file_path, zipfile, zipfile_path)
37+
else
38+
put_into_archive(disk_file_path, zipfile, zipfile_path)
39+
end
40+
end
41+
end
42+
43+
def recursively_deflate_directory(disk_file_path, zipfile, zipfile_path)
44+
zipfile.mkdir zipfile_path
45+
subdir = Dir.entries(disk_file_path) - %w(. ..)
46+
write_entries subdir, zipfile_path, zipfile
47+
end
48+
49+
def put_into_archive(disk_file_path, zipfile, zipfile_path)
50+
zipfile.get_output_stream(zipfile_path) do |f|
51+
f.write(File.open(disk_file_path, 'rb').read)
52+
end
53+
end
54+
end
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.lo-container
2+
%h1 Tracks
3+
%ul
4+
-@tracks.each do |track|
5+
%li= link_to track.title, [:admin, :data, track]
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.lo-container
2+
%h1= @track.title
3+
4+
%ul
5+
-@exercises.each do |exercise|
6+
%li= link_to exercise.title, [:admin, :data, @track, exercise]

config/routes.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@
3535
resources :iterations, only: [:show]
3636
end
3737
resources :mentors, only: [:index]
38+
namespace :data do
39+
resources :tracks, only: [:index, :show] do
40+
resources :exercises, only: [:show]
41+
end
42+
end
3843
end
3944

4045
# ###### #

0 commit comments

Comments
 (0)