Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

E2417. Reimplement the SubmittedContentController #78

Open
wants to merge 98 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
98 commits
Select commit Hold shift + click to select a range
b865ec3
Update README.md
Neel317 Mar 4, 2024
4c1ee86
Git Ignore Updated
Neel317 Mar 6, 2024
9e038ad
Updated seeds for default users
Neel317 Mar 6, 2024
0a00578
Merge branch 'main' of https://github.com/Neel317/reimplementation-ba…
Neel317 Mar 6, 2024
d7ef7d8
Added Display options model
Neel317 Mar 7, 2024
638e575
Merge pull request #1 from Neel317/display-option
Neel317 Mar 7, 2024
a0970b7
Logger message implemented.
Neel317 Mar 8, 2024
f5f83ab
Refactored expertiza logger.
Neel317 Mar 8, 2024
643dd3e
added some rspec test cases.
Neel317 Mar 8, 2024
c1d7b01
Merge pull request #2 from Neel317/errorlog
Neel317 Mar 8, 2024
fef721c
added necessary functions of submitted content controller.
Neel317 Mar 11, 2024
21f3eb0
added necessary functions for file_helper.
Neel317 Mar 11, 2024
4e1ade6
Merge pull request #3 from Neel317/helper-funcs
Neel317 Mar 11, 2024
5f283b4
Assignment_participant model and it's dependencies added.
Neel317 Mar 11, 2024
b4b9cef
Added sign up sheet and team since they go together.
Neel317 Mar 12, 2024
87b632f
Submission record model added.
Neel317 Mar 12, 2024
b00eaed
Added all the dependent models of sign up teams and sheet.
Neel317 Mar 12, 2024
c7ba61e
some more dependencies.
Neel317 Mar 12, 2024
a44bdbb
Assignment Model done.
Neel317 Mar 12, 2024
4857d03
Participant model has been completed.
Neel317 Mar 12, 2024
2dc7fb8
Merge pull request #4 from Neel317/models
Neel317 Mar 12, 2024
3c1a736
add routes related to submission of content
ashaka11 Mar 23, 2024
3d26cc4
add edit participant api to swagger
ashaka11 Mar 23, 2024
6d62782
Merge pull request #6 from Neel317/add-routes
Neel317 Mar 23, 2024
9de0fe5
update submitted content api
ashaka11 Mar 23, 2024
ca80753
add action_allowed method in submitted content controller
ashaka11 Mar 23, 2024
41e9e79
add controller locale method in submitted content controller
ashaka11 Mar 23, 2024
117be2a
add edit method in submitted content controller
ashaka11 Mar 23, 2024
cb6caba
added application controller and access,authorization helpers
maarjani23s Mar 24, 2024
e8958e7
Merge pull request #7 from Neel317/swagger-edit-api
Neel317 Mar 24, 2024
adfb6c7
Merge pull request #8 from Neel317/controller
Neel317 Mar 24, 2024
7e681df
Merge pull request #9 from Neel317/maarjani
maarjani23s Mar 24, 2024
591f35f
Added migrations
Neel317 Mar 24, 2024
09bab4b
Delete app/controllers/api/v1/application_controller.rb
Neel317 Mar 24, 2024
871496b
Merge pull request #10 from Neel317/maarjani
Neel317 Mar 24, 2024
820a06b
Merge branch 'main' of https://github.com/Neel317/reimplementation-ba…
Neel317 Mar 24, 2024
a1aca90
Merge pull request #11 from Neel317/migration
Neel317 Mar 24, 2024
ccccac2
Added final touch
Neel317 Mar 24, 2024
a963571
remove changes from gitignore
ashaka11 Mar 24, 2024
faea5bb
remove unwanted changes from README
ashaka11 Mar 24, 2024
54a91b5
remove unwanted changes from Gemfile and Gemfile.lock
ashaka11 Mar 24, 2024
db5b2d2
remove expertiza logger model
ashaka11 Mar 24, 2024
369a36e
remove changes from schema.rb
ashaka11 Mar 24, 2024
2337783
Merge pull request #13 from Neel317/keep-only-necessary-files
ashaka11 Mar 24, 2024
e5e0196
edit authorization helper
maarjani23s Mar 24, 2024
4109df5
Merge branch 'main' of https://github.com/Neel317/reimplementation-ba…
maarjani23s Mar 24, 2024
efdc868
Merge pull request #14 from Neel317/maarjani
maarjani23s Mar 24, 2024
386f161
Merge pull request #15 from Neel317/crud
ashaka11 Mar 24, 2024
873c1dc
remove access helper file
ashaka11 Mar 25, 2024
6217e53
remove authorization helper file
ashaka11 Mar 25, 2024
41d7ccc
remove assignment team model
ashaka11 Mar 25, 2024
65c3605
remove bid model
ashaka11 Mar 25, 2024
9307bb5
remove display option model
ashaka11 Mar 25, 2024
1820d6e
remove due date model
ashaka11 Mar 25, 2024
2c44272
join team request model
ashaka11 Mar 25, 2024
ccfdc04
remove logger message model
ashaka11 Mar 25, 2024
9cf245c
remove quiz response map model
ashaka11 Mar 25, 2024
004bfc9
remove quiz response model
ashaka11 Mar 25, 2024
a5c23b2
remove team node model
ashaka11 Mar 25, 2024
f9367bb
remove team user node model
ashaka11 Mar 25, 2024
a8d2760
Merge pull request #16 from Neel317/keep-only-necessary-files
ashaka11 Mar 25, 2024
9193774
remove unwanted changes from assignment participant, participant, tea…
ashaka11 Mar 25, 2024
3445783
remove unwanted changes from sign up sheet, sign upmtem, signed up te…
ashaka11 Mar 25, 2024
78ce9d9
Merge pull request #17 from Neel317/keep-only-necessary-files
ashaka11 Mar 25, 2024
79845e5
Delete spec/models/expertiza_logger_spec.rb
maarjani23s Mar 25, 2024
1f590c0
Added migrations for teams table.
Neel317 Apr 17, 2024
465b355
Added all the model changes with the required code.
Neel317 Apr 17, 2024
c98d70f
Added routes and helper functions for the controller.
Neel317 Apr 17, 2024
9bb3223
Adding the refactored and reimplemented submit content Controller.
Neel317 Apr 17, 2024
2fef601
Added some minor updates from new_feature branch. Got into issue in t…
Neel317 Apr 21, 2024
c368136
merge project-4 branch in main
ashaka11 Apr 22, 2024
d51709b
add comments of API endpoint for each method
ashaka11 Apr 23, 2024
412761b
change default host port to 3002
ashaka11 Apr 23, 2024
f056fb4
change default host port to 3002 for Swagger
ashaka11 Apr 23, 2024
4106944
add rspec for submit hyperlink post
ashaka11 Apr 23, 2024
fe75ac6
add rspec for submit hyperlink get
ashaka11 Apr 23, 2024
fc9e427
add rswag for download submmited content 200 response
ashaka11 Apr 23, 2024
04b9a84
add rswag for download submmited content 400 response
ashaka11 Apr 23, 2024
61c0895
add another rswag for download submmited content 400 response
ashaka11 Apr 23, 2024
1d1e0f3
add another rswag for download submmited content 400 response
ashaka11 Apr 23, 2024
c504123
add rswag for submit file
ashaka11 Apr 23, 2024
1b06983
add rswag for folder action
ashaka11 Apr 23, 2024
20670a3
add rswag for remove hyperlink
ashaka11 Apr 23, 2024
44c3a81
Minor changes and fixed move file endpoint
Neel317 Apr 23, 2024
9cf74d3
Merge branch 'project-4' of https://github.com/Neel317/reimplementati…
Neel317 Apr 23, 2024
ef61577
update rswag for file submission in Swagger UI
ashaka11 Apr 23, 2024
703d8f0
Some bug fixing and file folder updations
Neel317 Apr 23, 2024
0b18976
reorder api lisitings in Swagger
ashaka11 Apr 23, 2024
eeb832b
Merge branch 'tests' of https://github.com/Neel317/reimplementation-b…
ashaka11 Apr 23, 2024
f003a3c
add test for 200 response submit file
ashaka11 Apr 24, 2024
4e167b7
Minor bug fixes
Neel317 Apr 24, 2024
cc2486e
Merge branch 'tests' of https://github.com/Neel317/reimplementation-b…
Neel317 Apr 24, 2024
4e05470
Merge pull request #19 from Neel317/tests
Neel317 Apr 24, 2024
be57425
delete files generated while testing
ashaka11 Apr 24, 2024
6818be8
Update Gemfile to add rubyzip gem.
Neel317 Apr 24, 2024
313d8ee
Removed conjuction in naming of mehods and added comments to helper m…
Neel317 Apr 27, 2024
da62f05
Removed class instance methods from file helper.
Neel317 Apr 27, 2024
125155f
Fixed the method calls in the controller.
Neel317 Apr 27, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions Gemfile
Expand Up @@ -8,6 +8,7 @@ gem 'puma', '~> 5.0'
gem 'rails', '~> 7.0.4', '>= 7.0.4.2'
gem 'rswag-api'
gem 'rswag-ui'
gem 'rubyzip'

# Build JSON APIs with ease [https://github.com/rails/jbuilder]
# gem "jbuilder"
Expand Down
226 changes: 226 additions & 0 deletions app/controllers/api/v1/submitted_content_controller.rb
@@ -0,0 +1,226 @@
class Api::V1::SubmittedContentController < ApplicationController

include SubmittedContentHelper
include FileHelper

# Get /api/v1/submit_content
def index
@submission_record = SubmissionRecord.all
render json: @submission_record, status: :ok
end

# GET /api/v1/submitted_content/:id
def show
@submission_record = SubmissionRecord.find(params[:id])
render json: @submission_record, status: :ok
rescue ActiveRecord::RecordNotFound => e
render json: { error: e.message }, status: :not_found
end

# POST /api/v1/submitted_content
def create
@submission_record = SubmissionRecord.create(submitted_content_params)
if @submission_record.save
render json: @submission_record, status: :created
else
render json: @submission_record.errors, status: :unprocessable_entity
end
end

# POST /api/v1/submitted_content/submit_hyperlink
# GET /api/v1/submitted_content/submit_hyperlink
# Creates a submission record and submits the hyperlink.
def submit_hyperlink
set_participant

team = @participant.team
team_hyperlinks = team.hyperlinks
if team_hyperlinks.include?(params[:submission])
render json: { message: 'You or your teammate(s) have already submitted the same hyperlink.'}, status: :unprocessable_entity
else
store_hyperlink(team)
end
end

# POST /api/v1/submitted_content/remove_hyperlink
# GET /api/v1/submitted_content/remove_hyperlink
# Removes hyperlink from team submissions and creates a record.
def remove_hyperlink
set_participant

team = @participant.team
hyperlink_to_delete = team.hyperlinks[params['chk_links'].to_i]

delete_hyperlink(hyperlink_to_delete, team)
end

# POST /api/v1/submitted_content/submit_file
# GET /api/v1/submitted_content/submit_file
# To submit file to a specific student directory.
def submit_file
set_participant

@file = params[:uploaded_file]
file_size_limit = 5 # 5mb

unless check_content_size(@file, file_size_limit)
return render json: { message:"File size must be smaller than #{file_size_limit}MB" }, status: :bad_request
end

unless check_extension_integrity(@file.original_filename)
return render json: { message: 'File extension does not match. '\
'Please upload one of the following: '\
'pdf, png, jpeg, zip, tar, gz, 7z, odt, docx, md, rb, mp4, txt' }, status: :bad_request
end

@file_content = @file.read

team = @participant.team
team.set_student_directory_num

store_file

end

# POST /api/v1/submitted_content/folder_action
# GET /api/v1/submitted_content/folder_action
# Perform CRUD operations on the file uploaded.
def folder_action
set_participant

if params[:faction][:delete]
delete_selected_files
elsif params[:faction][:rename]
rename_selected_file
elsif params[:faction][:move]
move_selected_file
elsif params[:faction][:copy]
copy_selected_file
elsif params[:faction][:create]
create_new_folder
end
end

# GET /api/v1/submitted_content/download
# Checks for the required file and route and downloads the file.
def download
folder_name = params['current_folder']['name']
file_name = params['download']

if folder_name.nil?
render json: { message: 'Folder_name is nil.'}, status: :bad_request
elsif file_name.nil?
render json: { message: 'File name is nil.'}, status: :bad_request
elsif File.directory?("#{folder_name}/#{file_name}")
render json: { message: 'Cannot send a whole folder.'}, status: :bad_request
elsif !File.exist?("#{folder_name}/#{file_name}")
render json: { message: 'File does not exist.'}, status: :not_found
else
send_file("#{folder_name}/#{file_name}", disposition: 'inline')
render json: { message: 'File downloaded.' }, status: :ok
end
end

private

# Getting all the params from the request.
def submitted_content_params
params.require(:submitted_content).permit(:id, :content, :operation, :team_id, :user, :assignment_id)
end

# Setting the default instance variable participant.
def set_participant
@participant = AssignmentParticipant.find(params[:id])
end

# Assigns the directory path for the user
def set_current_folder
name = '/'
if params[:current_folder]
name = sanitize_folder(params[:current_folder][:name])
end
name
end

# Delete the selected file.
def delete_selected_files
filename = get_filename
FileUtils.rm_r(filename)
assignment = @participant.try(:assignment)
team = @participant.try(:team)
SubmissionRecord.create(team_id: team.try(:id),
content: filename,
user: @participant.user.try(:name),
assignment_id: assignment.try(:id),
operation: 'Remove File')
render json: { message: 'The selected file has been deleted.' }, status: :ok
rescue StandardError
render json: { error: "Failed to delete the file. Reason: #{$ERROR_INFO}" }, status: :unprocessable_entity
end

# Saving file to the newly created directory for submission
def save_file_to_directory(current_directory)
safe_filename = @file.original_filename.tr('\\', '/')
safe_filename = sanitize_filename(safe_filename)
full_filename = current_directory + File.split(safe_filename).last.tr(' ', '_')
File.open(full_filename, 'wb') { |f| f.write(@file_content) }
[full_filename, safe_filename]
end

# Creating submission record for submit_file function.
def create_submission_record(full_filename)
assignment = Assignment.find(@participant.assignment_id)
team = @participant.team
SubmissionRecord.create(team_id: team.id,
content: full_filename,
user: @participant.user.name,
assignment_id: assignment.id,
operation: 'Submit File')
render json: { message: 'The file has been submitted.' }, status: :ok
rescue StandardError
render json: { message: 'File record failed.' }, status: :unprocessable_entity
end

# Create a submission record for hyperlink submission.
def store_hyperlink(team)
begin
team.submit_hyperlink(params['submission'])
SubmissionRecord.create(team_id: team.id,
content: params['submission'],
user: @participant.user.name,
assignment_id: @participant.assignment.id,
operation: 'Submit Hyperlink')
rescue StandardError
return render json: { error: "The URL or URI is invalid. Reason: #{$ERROR_INFO}" }, status: :unprocessable_entity
end
render json: { message: 'The link has been successfully submitted.' }, status: :ok
end

# Remove hyperlink and create a submission record.
def delete_hyperlink(hyperlink_to_delete, team)
begin
team.remove_hyperlink(hyperlink_to_delete)
SubmissionRecord.create(team_id: team.id,
content: hyperlink_to_delete,
user: @participant.user.name,
assignment_id: @participant.assignment.id,
operation: 'Remove Hyperlink')
rescue StandardError
return render json: { error: "There was an error deleting the hyperlink. Reason: #{$ERROR_INFO}" }, status: :unprocessable_entity
end
render json: { message: 'The link has been successfully removed.' }, status: :ok
end

def store_file
current_folder = set_current_folder
current_directory = @participant.team.path.to_s + current_folder
FileUtils.mkdir_p(current_directory) unless File.exist? current_directory
full_filename, safe_filename = save_file_to_directory(current_directory)

# Unzip if specified in the parameters
if params['unzip']
SubmittedContentHelper.unzip_file(full_filename, current_directory, true) if file_type(safe_filename) == 'zip'
end
create_submission_record(full_filename)
end
end
40 changes: 40 additions & 0 deletions app/helpers/file_helper.rb
@@ -0,0 +1,40 @@
module FileHelper

# replace invalid characters with underscore
# valid: period
# underscore
# forward slash
# alphanumeric characters
def clean_path(file_name)
new_str = file_name.gsub(%r{[^\w\.\_/]}, '_')
new_str.tr("'", '_')
end

# Removes any extension or paths from file_name
# Also removes for invalid characters in filename
def sanitize_filename(file_name)
just_filename = File.basename(file_name)
FileHelper.clean_path(just_filename)
end

# Moves file from old location to a new location
def move_file(old_loc, new_loc)
new_dir, filename = File.split(new_loc)
new_dir = FileHelper.clean_path(new_dir)

FileHelper.create_directory_from_path(new_dir)
FileUtils.mv old_loc, File.join(new_dir, filename)
end

# Removes parent directory '..' from folder path.
def sanitize_folder(folder)
folder.gsub('..', '')
end

# Creates a new directory on the specified path.
def create_directory_from_path(path)
FileUtils.mkdir_p(path) unless File.exist? path
rescue StandardError => e
raise "An error occurred while creating this directory: #{e.message}"
end
end