diff --git a/tutor/app/assets/javascripts/solutions.js.coffee b/tutor/app/assets/javascripts/solutions.js.coffee index d1f32efd..addad684 100644 --- a/tutor/app/assets/javascripts/solutions.js.coffee +++ b/tutor/app/assets/javascripts/solutions.js.coffee @@ -277,6 +277,11 @@ debug_console = -> # Author: Rami Khalil + Khaled Helmy @jump_state = (state_number) -> highlight_line variables[state_number]['line'] + if state_number isnt 0 + clear_console() + $("#output_section").html variables[state_number]["stream"] + if variables[state_number]["exception"] + runtime_error variables[state_number]["exception"] update_memory_contents state_number # [View Variables - Story 3.7] diff --git a/tutor/app/assets/stylesheets/application.css b/tutor/app/assets/stylesheets/application.css index 2288e797..a3d0bb9a 100644 --- a/tutor/app/assets/stylesheets/application.css +++ b/tutor/app/assets/stylesheets/application.css @@ -11,6 +11,7 @@ *= require_self *= require_tree . */ += require posts .side-left { height:700px; diff --git a/tutor/app/assets/stylesheets/posts.css.scss b/tutor/app/assets/stylesheets/posts.css.scss index 1a7e1539..bec73e3c 100644 --- a/tutor/app/assets/stylesheets/posts.css.scss +++ b/tutor/app/assets/stylesheets/posts.css.scss @@ -1,3 +1,8 @@ -// Place all the styles related to the posts controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ +.greyLine { + border-bottom: 1px solid #D0D0D0; +} + +.reply { + padding-left:30px; + border-bottom: 1px solid #D0D0D0; +} \ No newline at end of file diff --git a/tutor/app/controllers/posts_controller.rb b/tutor/app/controllers/posts_controller.rb index afb13e76..345a576b 100644 --- a/tutor/app/controllers/posts_controller.rb +++ b/tutor/app/controllers/posts_controller.rb @@ -53,7 +53,9 @@ def destroy # Author: Ahmed Atef def show @post = Post.find(params[:id]) - @replies = @post.replies.order("created_at desc") + @post.views_count = @post.views_count + 1 + @post.save + @replies = @post.replies.order("created_at asc") end # [Add Post - Story 1.13] diff --git a/tutor/app/models/debugger.rb b/tutor/app/models/debugger.rb index 23fa4028..a430ab1e 100644 --- a/tutor/app/models/debugger.rb +++ b/tutor/app/models/debugger.rb @@ -62,21 +62,22 @@ def input(input) # Authors: Mussab ElDash + Rami Khalil def start(class_name, input) $all = [] + source_path = "#{Rails.root.to_s}/#{Solution::JAVA_PATH}" Dir.chdir(Solution::CLASS_PATH){ begin - $input, $output, $error, $wait_thread = Open3.popen3("jdb", class_name, *input) + $input, $output, $error, $wait_thread = Open3.popen3("jdb", + "-sourcepath", source_path, class_name, *input) buffer_until_ready input "stop in #{class_name}.main" buffer_until_ready input "run" - num = get_line + nums = get_line locals = get_variables - hash = {:line => num, :locals => locals} - $all << hash + nums[:locals] = locals + $all << nums debug rescue => e unless e.message === 'Exited' - p e.message return false end end @@ -84,7 +85,6 @@ def start(class_name, input) begin Process.kill("TERM", $wait_thread.pid) rescue => e - p e.message end return $all end @@ -99,10 +99,14 @@ def debug while counter < 100 && !$input.closed? do begin input "step" - num = get_line - locals = get_variables - hash = {:line => num, :locals => locals} - $all << hash + nums = get_line + locals = [] + begin + locals = get_variables + rescue => e + end + nums[:locals] = locals + $all << nums counter += 1 rescue => e $input.close @@ -118,24 +122,83 @@ def debug # Author: Mussab ElDash def get_line out_stream = buffer_until_complete - list_of_lines = out_stream.split(/\n+/) - before_last_line = list_of_lines[-2] - /, line=\d+/ =~ before_last_line - before_last_regex_capture = $& - /\d+/ =~ before_last_regex_capture - before_last_regex_capture = $& - last_line = list_of_lines[-2] - /^\d+/=~ last_line - last_regex_capture = $& - if last_regex_capture - return last_regex_capture.to_i - elsif before_last_regex_capture - return before_last_regex_capture.to_i + exceptions = has_exception out_stream + stream = get_stream out_stream + /,\sline=\d+/ =~ out_stream + line_first = $& + begin + input "list" + out_stream = buffer_until_complete + /\n\d+\s=>/ =~ out_stream + line_second = $& + rescue => e + end + if line_first + line_first = line_first[7..-1] + exceptions[:line] = line_first.to_i + if $all[-1] + exceptions[:stream] = "#{$all[-1][:stream]}#{stream}" + else + exceptions[:stream] = "" + end + return exceptions + elsif line_second + line_second = line_second[0..-4] + exceptions[:line] = line_second.to_i + return exceptions else raise 'Exited' end end + # [Debugger: Debug - Story 3.6] + # Checks if there is a runtime error thrown + # Parameters: + # line: The line to be checked if it has a runtime error + # Returns: A hash of the exception and its explanation if exists + # Author: Mussab ElDash + def get_stream(line) + /^>\s.+\n/ =~ line + stream = $& + if stream + stream = stream[2..-1] + p stream + return stream + end + return "" + end + + # [Debugger: Debug - Story 3.6] + # Checks if there is a runtime error thrown + # Parameters: + # line: The line to be checked if it has a runtime error + # Returns: A hash of the exception and its explanation if exists + # Author: Mussab ElDash + def has_exception(line) + /Exception occurred: / =~ line + if $& + exception = get_exception + return {:status => false, :exception => Executer.get_runtime_explaination(exception)} + end + return {:status => true} + end + + # [Debugger: Debug - Story 3.6] + # Checks if there is a runtime error thrown + # Parameters: + # line: The line to be checked if it has a runtime error + # Returns: A hash of the exception and its explanation if exists + # Author: Mussab ElDash + def get_exception + input "step" + out_stream = buffer_until_complete + ragex_first = /[[:space:]]+at\s[[:alnum:]]+\.main\([[:alnum:]]+\.java:\d+\)/m + regex_second = /[[:space:]]+The application exited\n*/ + regex = /#{ragex_first}#{regex_second}/ + out_stream = out_stream.sub(regex, "") + return out_stream + end + # [Debugger: Debug - Story 3.6] # Create a java file and start debugging # Parameters: @@ -153,7 +216,7 @@ def self.debug(student_id, problem_id, code, input) return {:success => false, data: compile_status} end debugger = Debugger.new - class_name = solution.class_file_name + class_name = solution.file_name debugging = debugger.start(class_name, input.split(" ")) java_file = solution.java_file_name true, true class_file = solution.class_file_name true, true diff --git a/tutor/app/models/executer.rb b/tutor/app/models/executer.rb index ad5512e6..ce21e6c9 100644 --- a/tutor/app/models/executer.rb +++ b/tutor/app/models/executer.rb @@ -87,18 +87,41 @@ def self.remove_class_name(file_name, error, sub_name) # A hash [error, explanation], where error is the runtime error and explanation # is a custom message to explain the error # Author: Ahmed Akram + def self.get_runtime_error(file_name, sub_name) + execute_res = remove_class_name(file_name, execute_res, sub_name) + return get_runtime_explaination(execute_res) + end + + # [Debugger: Debug - Story 3.6] + # Returns a message explaining what this error is + # Parameters: + # exception: The exception to be explained + # Returns: The Explanation of the exception given + # Author: Mussab ElDash + def self.get_runtime_explaination(exception) + if exception.include?("/ by zero") || exception.include?("ArithmeticException") + message = "Division by Zero results in infinity, " + + "which computers can not understand. Be careful !" + return {errors: exception, explanation: message} + else + message = "To be set Runtime Error!" + return {errors: exception, explanation: message} + end + end + + # [Compiler: Test - Story 3.15] + # Returns the runtime error and a message + # Parameters: + # file_name: The submitted file name + # sub_name: The name to replace the class name + # Returns: A hash [error, explanation], where error is the runtime error and explanation + # is a custom message to explain the error + # Author: Ahmed Akram def self.get_runtime_error file_name = @solution.file_name sub_name = 'CoolSoft' @execute_res = remove_class_name(file_name, @execute_res, sub_name) - if @execute_res.include?("/ by zero") - message = "Division by Zero results in infinity, "\ - "which computers can not understand. Be careful !" - return msg = {errors: @execute_res, explanation: message} - else - message = "To be set Runtime Error!" - return msg = {errors: @execute_res, explanation: message} - end + return get_runtime_explaination @execute_res end # [Compiler: Test - Story 3.15] @@ -112,4 +135,4 @@ def self.get_output return {success: true, message: @execute_res} end -end \ No newline at end of file +end diff --git a/tutor/app/models/post.rb b/tutor/app/models/post.rb index 844360c1..c66e387b 100644 --- a/tutor/app/models/post.rb +++ b/tutor/app/models/post.rb @@ -17,6 +17,12 @@ class Post < ActiveRecord::Base #Methods + def most_recent_reply + reply = Reply.first(:order => 'created_at DESC', + :conditions => ['post_id = ?', self.id]) + return reply + end + # [Advanced Search - Story 1.23] # search for posts # Parameters: hash of search options @@ -44,4 +50,5 @@ def self.search(params) end end end + end diff --git a/tutor/app/views/discussion_boards/show.html.erb b/tutor/app/views/discussion_boards/show.html.erb index 9688d8b1..7becd032 100644 --- a/tutor/app/views/discussion_boards/show.html.erb +++ b/tutor/app/views/discussion_boards/show.html.erb @@ -1,30 +1,71 @@ -
- <% if flash[:notice] %> -
<%= flash[:notice] %>
- <% end %> - <% if @discussionBoard.activated == true %> -
+<% if flash[:notice] %> +
<%= flash[:notice] %>
+<% end %> +<% if @discussionBoard.activated == true %> + +

<%= @discussionBoard.title %>

- <% unless @posts.blank? %> - <% @posts.each do |post| %> -
-
- <%= post.views_count %> - -
- <% end %> - <% else %> - No Posts Yet .. Try Creating a Post - <% end %> -
- <%= link_to "Add Post", new_post_path(discussion_board_id: - @discussionBoard.id), class: "btn btn-success", - style: "float: left;margin-left: 15px" %> -
- <% else %> - The discusstion board is deactivated - <% end %> - \ No newline at end of file + <% unless @posts.blank? %> + + + + + + + + + <% @posts.each do |post| %> + + + + + + + + + <% end %> + <% else %> + No Posts Yet .. Try Creating a Post + <% end %> +
<%= link_to post.title, :controller => 'posts', :action=> 'show', - :id => post.id,:method => :get, class: "btn btn-success" %> -
PostRepliesPost OwnerLast Reply CreatedViews
+

<%= link_to post.title, :controller => 'posts', :action=> 'show', + :id => post.id,:method => :get, class: + "btn btn-success" %>

+
+ <%= post.replies.count %>
+
+ <%= post.owner.name %>'s post
+
+ <% if post.most_recent_reply %> + <%= distance_of_time_in_words_to_now post.most_recent + _reply.created_at %> ago by + <% if post.most_recent_reply.owner_type == "Lecturer" %> + <%= link_to post.most_recent_reply.owner.name, + "/lecturers/{post.most_recent_reply.owner_id}" %> + <% end %> + <% if post.most_recent_reply.owner_type == "Student" %> + <%= link_to post.most_recent_reply.owner.name, + "/students/{post.most_recent_reply.owner_id}" %> + <% end %> + <% if post.most_recent_reply.owner_type == "TeachingAssistant" %> + <%= link_to post.most_recent_reply.owner.name, + "/teachingassistants/{post.most_recent_reply.owner_id}" %> + <% end %> + <% else %> + No replies + <% end %> + + <%=distance_of_time_in_words_to_now post.created_at %> ago +
+
+ <%= post.views_count %>
+
+
+ <%= link_to "Add Post", new_post_path(discussion_board_id: + @discussionBoard.id), class: "btn btn-success" %> +
+<% else %> + The discusstion board is deactivated +<% end %> \ No newline at end of file diff --git a/tutor/app/views/posts/show.html.erb b/tutor/app/views/posts/show.html.erb index 7f06d3b2..d230a5ce 100644 --- a/tutor/app/views/posts/show.html.erb +++ b/tutor/app/views/posts/show.html.erb @@ -5,33 +5,49 @@ <%= link_to "back", {:action => 'show', :controller => 'discussion_boards', :id => DiscussionBoard.find_by_id(@post.discussion_board_id).course_id}, { class: 'btn btn-primary'} %> -
- <% if current_lecturer %> - <% @userID = current_lecturer.id %> - <% end %> - <% if current_student %> - <% @userID = current_student.id %> - <% end %> - <%if current_teaching_assistant %> - <% @userID = current_teaching_assistant.id %> - <% end %> -
-

<%=@post.title%>

- <%= @post.content %> -
+<% if current_lecturer %> + <% @userID = current_lecturer.id %> +<% end %> +<% if current_student %> + <% @userID = current_student.id %> +<% end %> +<%if current_teaching_assistant %> + <% @userID = current_teaching_assistant.id %> +<% end %> +<% if @post.owner_id == @userID %> + <%= link_to "Edit Post", {:action => 'edit', :controller => 'posts'}, { + class: 'btn btn-primary',:id => @post.id} %> +<% end %> +
+
+

<%= @post.title %>

+
+
+

<%= @post.owner.name %>

+

<%= @post.content %>

+

<%= distance_of_time_in_words_to_now @post. + created_at %> ago

+
+
+
<% unless @replies.blank? %> <% @replies.each do |reply| %> -
- <%= reply.content %>
+
+
+ <%= reply.owner.name %> +
+
+

<%= reply.content %>

+

<%= distance_of_time_in_words_to_now reply. + created_at %> ago

+
+
-
<% end %> <% else %> - No Replies in this post yet . +
+ No replies in this post yet. +
<% end %>
- <% if @post.owner_id == @userID %> - <%= link_to "Edit Post", {:action => 'edit', :controller => 'posts'}, { - class: 'btn btn-primary',:id => @post.id} %> - <% end %>
\ No newline at end of file diff --git a/tutor/app/views/solutions/_new.html.erb b/tutor/app/views/solutions/_new.html.erb index a56fa566..3e2486d6 100644 --- a/tutor/app/views/solutions/_new.html.erb +++ b/tutor/app/views/solutions/_new.html.erb @@ -1,4 +1,3 @@ -

<%= flash[:alert] %>

Time spent: 0:00 @@ -68,6 +67,7 @@
+
-