@@ -23,13 +23,23 @@ def new; end
2323 action_auth_level :create , :administrator
2424 def create
2525 @scheduler = @course . scheduler . new ( scheduler_params )
26- if @scheduler . save
27- flash [ :success ] = "Scheduler created!"
28- redirect_to ( course_schedulers_path ( @course ) )
29- else
30- flash [ :error ] = "Scheduler create failed. Please check all fields."
31- redirect_to ( new_course_scheduler_path ( @course ) )
26+ action_path = Rails . root . join ( scheduler_params [ :action ] ) . to_path
27+ # Check if the action file exists, is readable, and compiles
28+ if validate_compile_action_file ( action_path )
29+ if @scheduler . save
30+ # Ensure visual run is successful
31+ if run_visual_scheduler ( @scheduler )
32+ flash [ :success ] = "Scheduler created and executed successfully!"
33+ redirect_to ( course_schedulers_path ( @course ) ) and return
34+ else
35+ @scheduler . destroy
36+ flash [ :error ] = "Scheduler creation failed during execution."
37+ end
38+ else
39+ flash [ :error ] = "Scheduler create failed. Please check all fields."
40+ end
3241 end
42+ redirect_to ( new_course_scheduler_path ( @course ) )
3343 end
3444
3545 action_auth_level :edit , :administrator
@@ -44,56 +54,32 @@ def run
4454
4555 action_auth_level :visual_run , :administrator
4656 def visual_run
47- action = Scheduler . find ( params [ :scheduler_id ] )
48- # https://stackoverflow.com/a/1076445
49- read , write = IO . pipe
50- @log = "Executing #{ Rails . root . join ( action . action ) } \n "
51- begin
52- pid = fork do
53- read . close
54- mod_name = Rails . root . join ( action . action ) . to_path
55- fork_log = ""
56- begin
57- require mod_name
58- output = Updater . update ( action . course )
59- if output . respond_to? ( :to_str )
60- fork_log << "----- Script Output -----\n "
61- fork_log << output
62- fork_log << "\n ----- End Script Output -----"
63- end
64- rescue ScriptError , StandardError => e
65- fork_log << "----- Script Error Output -----\n "
66- fork_log << "Error in '#{ @course . name } ' updater: #{ e . message } \n "
67- fork_log << e . backtrace . join ( "\n \t " )
68- fork_log << "\n ---- End Script Error Output -----"
69- end
70- write . print fork_log
71- end
72-
73- write . close
74- result = read . read
75- Process . wait2 ( pid )
76- @log << result
77- rescue StandardError => e
78- @log << "----- Error Output -----\n "
79- @log << "Error in '#{ @course . name } ' updater: #{ e . message } \n "
80- @log << e . backtrace . join ( "\n \t " )
81- @log << "\n ---- End Error Output -----"
82- end
83- @log << "\n Completed running action."
57+ @scheduler = Scheduler . find ( params [ :scheduler_id ] )
58+ @log = execute_action ( @scheduler )
8459 render partial : "visual_test"
8560 end
8661
8762 action_auth_level :update , :administrator
8863 def update
8964 @scheduler = Scheduler . find_by ( id : params [ :id ] )
90- if @scheduler &.update ( scheduler_params )
91- flash [ :success ] = "Scheduler updated."
92- redirect_to ( course_schedulers_path ( @course ) )
93- else
94- flash [ :error ] = "Scheduler update failed! Please check your fields."
95- redirect_to ( edit_course_scheduler_path ( @course , @scheduler ) )
65+ action_path = Rails . root . join ( scheduler_params [ :action ] ) . to_path
66+ # Check if the action file exists, is readable, and compiles
67+ if validate_compile_action_file ( action_path )
68+ previous_state = @scheduler . attributes
69+ if @scheduler . update ( scheduler_params )
70+ # Ensure visual run is successful
71+ if run_visual_scheduler ( @scheduler )
72+ flash [ :success ] = "Scheduler updated and executed successfully!"
73+ redirect_to ( course_schedulers_path ( @course ) ) and return
74+ else
75+ @scheduler . update ( previous_state ) # If error, revert to previous state.
76+ flash [ :error ] = "Scheduler update failed during execution. Reverted to previous state."
77+ end
78+ else
79+ flash [ :error ] = "Scheduler update failed! Please check your fields."
80+ end
9681 end
82+ redirect_to ( edit_course_scheduler_path ( @course , @scheduler ) )
9783 end
9884
9985 action_auth_level :destroy , :administrator
@@ -119,4 +105,79 @@ def set_manage_scheduler_breadcrumb
119105
120106 @breadcrumbs << ( view_context . link_to "Manage Schedulers" , course_schedulers_path ( @course ) )
121107 end
108+
109+ def validate_compile_action_file ( action_path )
110+ # Check if the action file exists and is readable
111+ unless File . exist? ( action_path ) && File . readable? ( action_path )
112+ flash [ :error ] = "Scheduler update failed. Action file does not exist or is
113+ not readable at #{ action_path } ."
114+ return false
115+ end
116+
117+ # compile action file to check for syntax errors
118+ begin
119+ RubyVM ::InstructionSequence . compile ( File . read ( action_path ) )
120+ rescue SyntaxError => e
121+ flash [ :error ] = "Syntax error in action file: #{ e . message } "
122+ return false
123+ rescue StandardError => e
124+ flash [ :error ] = "Error validating action file: #{ e . message } "
125+ return false
126+ end
127+
128+ true
129+ end
130+
131+ def run_visual_scheduler ( scheduler )
132+ log = execute_action ( scheduler )
133+ # Ensure visual run is successful or return error
134+ if log . include? ( "Error" )
135+ flash [ :error ] = "Scheduler execution failed."
136+ false
137+ else
138+ flash [ :success ] = "Scheduler executed successfully!"
139+ true
140+ end
141+ end
142+
143+ def execute_action ( scheduler )
144+ action_path = Rails . root . join ( scheduler . action ) . to_path
145+ # https://stackoverflow.com/a/1076445
146+ read , write = IO . pipe
147+ log = "Executing #{ action_path } \n "
148+ begin
149+ pid = fork do
150+ read . close
151+ mod_name = action_path
152+ fork_log = ""
153+ begin
154+ require mod_name
155+ output = Updater . update ( scheduler . course )
156+ if output . respond_to? ( :to_str )
157+ fork_log << "----- Script Output -----\n "
158+ fork_log << output
159+ fork_log << "\n ----- End Script Output -----"
160+ end
161+ rescue ScriptError , StandardError => e
162+ fork_log << "----- Script Error Output -----\n "
163+ fork_log << "Error in '#{ scheduler . course . name } ' updater: #{ e . message } \n "
164+ fork_log << e . backtrace . join ( "\n \t " )
165+ fork_log << "\n ---- End Script Error Output -----"
166+ end
167+ write . print fork_log
168+ end
169+
170+ write . close
171+ result = read . read
172+ Process . wait2 ( pid )
173+ log << result
174+ rescue StandardError => e
175+ log << "----- Error Output -----\n "
176+ log << "Error during execution: #{ e . message } \n "
177+ log << e . backtrace . join ( "\n \t " )
178+ log << "\n ---- End Error Output -----"
179+ end
180+ log << "\n Completed running action."
181+ log
182+ end
122183end
0 commit comments