Andrew Cantino 11 лет назад
Родитель
Сommit
f8ee5e3ec4

+ 6 - 3
app/assets/javascripts/application.js.coffee.erb

@@ -99,9 +99,12 @@ $(document).ready ->
         $("#logs .spinner").stop(true, true).fadeOut ->
         $("#logs .spinner").stop(true, true).fadeOut ->
           $("#logs .refresh, #logs .clear").show()
           $("#logs .refresh, #logs .clear").show()
 
 
-  $(".agent-show #show-tabs a[href='#logs']").on "click", fetchLogs
-  $("#logs .refresh").on "click", fetchLogs
-  $("#logs .clear").on "click", clearLogs
+  $(".agent-show #show-tabs a[href='#logs'], #logs .refresh").on "click", fetchLogs
+  $(".agent-show #logs .clear").on "click", clearLogs
+
+  if tab = window.location.href.match(/tab=(\w+)\b/i)?[1]
+    if tab in ["details", "logs"]
+      $(".agent-show .nav-tabs li a[href='##{tab}']").click()
 
 
   # Editing Agents
   # Editing Agents
   $("#agent_source_ids").on "change", showEventDescriptions
   $("#agent_source_ids").on "change", showEventDescriptions

+ 6 - 1
app/assets/stylesheets/application.css.scss.erb

@@ -82,6 +82,11 @@ img.spinner {
   overflow: hidden;
   overflow: hidden;
 }
 }
 
 
+span.not-applicable:after {
+  color: #bbbbbb;
+  content: "n/a";
+}
+
 // Navbar
 // Navbar
 
 
 #job-indicator, #event-indicator {
 #job-indicator, #event-indicator {
@@ -116,4 +121,4 @@ img.spinner {
   &.refresh {
   &.refresh {
     margin: 0 10px;
     margin: 0 10px;
   }
   }
-}
+}

+ 1 - 1
app/helpers/application_helper.rb

@@ -11,7 +11,7 @@ module ApplicationHelper
     if agent.working?
     if agent.working?
       '<span class="label label-success">Yes</span>'.html_safe
       '<span class="label label-success">Yes</span>'.html_safe
     else
     else
-      '<span class="label label-warning">No</span>'.html_safe
+      link_to '<span class="label label-warning">No</span>'.html_safe, agent_path(agent, :tab => (agent.recent_error_logs? ? 'logs' : 'details'))
     end
     end
   end
   end
 end
 end

+ 22 - 2
app/models/agent.rb

@@ -88,7 +88,11 @@ class Agent < ActiveRecord::Base
   end
   end
 
 
   def create_event(attrs)
   def create_event(attrs)
-    events.create!({ :user => user }.merge(attrs))
+    if can_create_events?
+      events.create!({ :user => user }.merge(attrs))
+    else
+      error "This Agent cannot create events!"
+    end
   end
   end
 
 
   def validate_schedule
   def validate_schedule
@@ -117,7 +121,7 @@ class Agent < ActiveRecord::Base
   end
   end
 
 
   def last_event_at
   def last_event_at
-    @memoized_last_event_at ||= events.select(:created_at).first.try(:created_at)
+    @memoized_last_event_at ||= most_recent_event.try(:created_at)
   end
   end
 
 
   def default_schedule
   def default_schedule
@@ -140,6 +144,14 @@ class Agent < ActiveRecord::Base
     !cannot_receive_events?
     !cannot_receive_events?
   end
   end
 
 
+  def cannot_create_events?
+    self.class.cannot_create_events?
+  end
+
+  def can_create_events?
+    !cannot_create_events?
+  end
+
   def set_last_checked_event_id
   def set_last_checked_event_id
     if newest_event_id = Event.order("id desc").limit(1).pluck(:id).first
     if newest_event_id = Event.order("id desc").limit(1).pluck(:id).first
       self.last_checked_event_id = newest_event_id
       self.last_checked_event_id = newest_event_id
@@ -169,6 +181,14 @@ class Agent < ActiveRecord::Base
       @default_schedule
       @default_schedule
     end
     end
 
 
+    def cannot_create_events!
+      @cannot_create_events = true
+    end
+
+    def cannot_create_events?
+      !!@cannot_create_events
+    end
+
     def cannot_receive_events!
     def cannot_receive_events!
       @cannot_receive_events = true
       @cannot_receive_events = true
     end
     end

+ 2 - 0
app/models/agents/digest_email_agent.rb

@@ -3,6 +3,8 @@ module Agents
     MAIN_KEYS = %w[title message text main value].map(&:to_sym)
     MAIN_KEYS = %w[title message text main value].map(&:to_sym)
     default_schedule "5am"
     default_schedule "5am"
 
 
+    cannot_create_events!
+
     description <<-MD
     description <<-MD
       The DigestEmailAgent collects any Events sent to it and sends them all via email when run.
       The DigestEmailAgent collects any Events sent to it and sends them all via email when run.
       The email will be sent to your account's address and will have a `subject` and an optional `headline` before
       The email will be sent to your account's address and will have a `subject` and an optional `headline` before

+ 1 - 0
app/models/agents/post_agent.rb

@@ -1,6 +1,7 @@
 module Agents
 module Agents
   class PostAgent < Agent
   class PostAgent < Agent
     cannot_be_scheduled!
     cannot_be_scheduled!
+    cannot_create_events!
 
 
     description <<-MD
     description <<-MD
        Post Agent receives events from other agents and send those events as the contents of a post request to a specified url. `post_url` field must specify where you would like to receive post requests and do not forget to include URI scheme (`http` or `https`)
        Post Agent receives events from other agents and send those events as the contents of a post request to a specified url. `post_url` field must specify where you would like to receive post requests and do not forget to include URI scheme (`http` or `https`)

+ 1 - 0
app/models/agents/twilio_agent.rb

@@ -4,6 +4,7 @@ require 'securerandom'
 module Agents
 module Agents
   class TwilioAgent < Agent
   class TwilioAgent < Agent
     cannot_be_scheduled!
     cannot_be_scheduled!
+    cannot_create_events!
 
 
     description <<-MD
     description <<-MD
       The TwilioAgent receives and collects events and sends them via text message or gives you a call when scheduled.
       The TwilioAgent receives and collects events and sends them via text message or gives you a call when scheduled.

+ 2 - 1
app/views/agents/_form.html.erb

@@ -47,8 +47,9 @@
   <div class="control-group">
   <div class="control-group">
     <%= f.label :sources, :class => 'control-label' %>
     <%= f.label :sources, :class => 'control-label' %>
     <div class="controls link-region" data-can-receive-events="<%= @agent.can_receive_events? %>">
     <div class="controls link-region" data-can-receive-events="<%= @agent.can_receive_events? %>">
+      <% eventSources = (current_user.agents - [@agent]).find_all { |a| a.can_create_events? } %>
       <%= f.select(:source_ids,
       <%= f.select(:source_ids,
-                   options_for_select((current_user.agents - [@agent]).map {|s| [s.name, s.id] },
+                   options_for_select(eventSources.map {|s| [s.name, s.id] },
                                       @agent.source_ids),
                                       @agent.source_ids),
                    {}, { :multiple => true, :size => 5, :class => 'span4 select2' }) %>
                    {}, { :multiple => true, :size => 5, :class => 'span4 select2' }) %>
       <span class='cannot-receive-events text-info'>This type of Agent cannot receive events.</span>
       <span class='cannot-receive-events text-info'>This type of Agent cannot receive events.</span>

+ 55 - 37
app/views/agents/index.html.erb

@@ -8,53 +8,71 @@
       <table class='table table-striped'>
       <table class='table table-striped'>
         <tr>
         <tr>
           <th>Name</th>
           <th>Name</th>
+          <th>Schedule</th>
           <th>Last Check</th>
           <th>Last Check</th>
           <th>Last Event Out</th>
           <th>Last Event Out</th>
           <th>Last Event In</th>
           <th>Last Event In</th>
-          <th>Events</th>
-          <th>Schedule</th>
+          <th>Events Created</th>
           <th>Working?</th>
           <th>Working?</th>
           <th></th>
           <th></th>
         </tr>
         </tr>
 
 
         <% @agents.each do |agent| %>
         <% @agents.each do |agent| %>
-            <tr>
-              <td>
-                <%= agent.name %>
-                <br/>
-                <span class='muted'><%= agent.short_type.titleize %></span>
-              </td>
-              <td>
-                <% if agent.cannot_be_scheduled? %>
-                    N/A
-                <% else %>
-                    <%= agent.last_check_at ? time_ago_in_words(agent.last_check_at) + " ago" : "never" %>
-                <% end %>
-              </td>
-              <td><%= agent.last_event_at ? time_ago_in_words(agent.last_event_at) + " ago" : "never" %></td>
-              <td>
-                <% if agent.cannot_receive_events? %>
-                    N/A
+          <tr>
+            <td>
+              <%= agent.name %>
+              <br/>
+              <span class='muted'><%= agent.short_type.titleize %></span>
+            </td>
+            <td>
+              <% if agent.can_be_scheduled? %>
+                <%= agent.schedule.to_s.humanize.titleize %>
+              <% else %>
+                <span class='not-applicable'></span>
+              <% end %>
+            </td>
+            <td>
+              <% if agent.can_be_scheduled? %>
+                <%= agent.last_check_at ? time_ago_in_words(agent.last_check_at) + " ago" : "never" %>
+              <% else %>
+                <span class='not-applicable'></span>
+              <% end %>
+            </td>
+            <td>
+              <% if agent.can_create_events? %>
+                <%= agent.last_event_at ? time_ago_in_words(agent.last_event_at) + " ago" : "never" %>
+              <% else %>
+                <span class='not-applicable'></span>
+              <% end %>
+            </td>
+            <td>
+              <% if agent.can_receive_events? %>
+                <%= agent.last_receive_at ? time_ago_in_words(agent.last_receive_at) + " ago" : "never" %>
+              <% else %>
+                <span class='not-applicable'></span>
+              <% end %>
+            </td>
+            <td>
+              <% if agent.can_create_events? %>
+                <%= link_to(agent.events_count || 0, events_path(:agent => agent.to_param)) %>
+              <% else %>
+                <span class='not-applicable'></span>
+              <% end %>
+            </td>
+            <td><%= working(agent) %></td>
+            <td>
+              <div class="btn-group">
+                <%= link_to 'Show', agent_path(agent), class: "btn btn-mini" %>
+                <%= link_to 'Edit', edit_agent_path(agent), class: "btn btn-mini" %>
+                <%= link_to 'Delete', agent_path(agent), method: :delete, data: { confirm: 'Are you sure?' }, class: "btn btn-mini" %>
+                <% if agent.can_be_scheduled? %>
+                  <%= link_to 'Run', run_agent_path(agent, :return => "index"), method: :post, class: "btn btn-mini" %>
                 <% else %>
                 <% else %>
-                    <%= agent.last_receive_at ? time_ago_in_words(agent.last_receive_at) + " ago" : "never" %>
+                  <%= link_to 'Run', "#", class: "btn btn-mini disabled" %>
                 <% end %>
                 <% end %>
-              </td>
-              <td><%= link_to(agent.events_count || 0, events_path(:agent => agent.to_param)) %></td>
-              <td><%= (agent.schedule || "n/a").to_s.humanize.titleize %></td>
-              <td><%= working(agent) %></td>
-              <td>
-                <div class="btn-group">
-                  <%= link_to 'Show', agent_path(agent), class: "btn btn-mini" %>
-                  <%= link_to 'Edit', edit_agent_path(agent), class: "btn btn-mini" %>
-                  <%= link_to 'Delete', agent_path(agent), method: :delete, data: {confirm: 'Are you sure?'}, class: "btn btn-mini" %>
-                  <% if agent.can_be_scheduled? %>
-                      <%= link_to 'Run', run_agent_path(agent, :return => "index"), method: :post, class: "btn btn-mini" %>
-                  <% else %>
-                      <%= link_to 'Run', "#", class: "btn btn-mini disabled" %>
-                  <% end %>
-                </div>
-              </td>
-            </tr>
+              </div>
+            </td>
+          </tr>
         <% end %>
         <% end %>
       </table>
       </table>
 
 

+ 50 - 28
app/views/agents/show.html.erb

@@ -13,7 +13,7 @@
           <% end %>
           <% end %>
           <li><a href="#logs" data-toggle="tab" data-agent-id="<%= @agent.id %>"><i class='icon-list-alt'></i> Logs</a></li>
           <li><a href="#logs" data-toggle="tab" data-agent-id="<%= @agent.id %>"><i class='icon-list-alt'></i> Logs</a></li>
 
 
-          <% if @agent.events.count > 0 %>
+          <% if @agent.can_create_events? && @agent.events.count > 0 %>
             <li><%= link_to '<i class="icon-random"></i> Events'.html_safe, events_path(:agent => @agent.to_param) %></li>
             <li><%= link_to '<i class="icon-random"></i> Events'.html_safe, events_path(:agent => @agent.to_param) %></li>
           <% end %>
           <% end %>
           <li><%= link_to '<i class="icon-chevron-left"></i> Back'.html_safe, agents_path %></li>
           <li><%= link_to '<i class="icon-chevron-left"></i> Back'.html_safe, agents_path %></li>
@@ -29,7 +29,7 @@
                   </li>
                   </li>
                 <% end %>
                 <% end %>
 
 
-                <% if @agent.events.count > 0 %>
+                <% if @agent.can_create_events? && @agent.events.count > 0 %>
                   <li>
                   <li>
                     <%= link_to '<i class="icon-trash"></i> Delete all events'.html_safe, remove_events_agent_path(@agent), method: :delete, data: {confirm: 'Are you sure you want to delete ALL events for this Agent?'}, :tabindex => "-1" %>
                     <%= link_to '<i class="icon-trash"></i> Delete all events'.html_safe, remove_events_agent_path(@agent), method: :delete, data: {confirm: 'Are you sure you want to delete ALL events for this Agent?'}, :tabindex => "-1" %>
                   </li>
                   </li>
@@ -70,38 +70,60 @@
               <%= @agent.short_type.titleize %>
               <%= @agent.short_type.titleize %>
             </p>
             </p>
 
 
-            <p>
-              <b>Schedule:</b>
-              <%= (@agent.schedule || "n/a").humanize.titleize %>
-            </p>
+            <% if @agent.can_be_scheduled? %>
+              <p>
+                <b>Schedule:</b>
+                <%= (@agent.schedule || "n/a").humanize.titleize %>
+              </p>
 
 
-            <p>
-              <b>Last checked:</b>
-              <% if @agent.cannot_be_scheduled? %>
-                N/A
-              <% else %>
+              <p>
+                <b>Last checked:</b>
                 <%= @agent.last_check_at ? time_ago_in_words(@agent.last_check_at) + " ago" : "never" %>
                 <%= @agent.last_check_at ? time_ago_in_words(@agent.last_check_at) + " ago" : "never" %>
-              <% end %>
-            </p>
+              </p>
+            <% end %>
 
 
-            <p>
-              <b>Last event created:</b>
-              <%= @agent.last_event_at ? time_ago_in_words(@agent.last_event_at) + " ago" : "never" %>
-            </p>
+            <% if @agent.can_create_events? %>
+              <p>
+                <b>Last event created:</b>
+                <%= @agent.last_event_at ? time_ago_in_words(@agent.last_event_at) + " ago" : "never" %>
+              </p>
+            <% end %>
 
 
-            <p>
-              <b>Last received event:</b>
-              <% if @agent.cannot_receive_events? %>
-                N/A
-              <% else %>
+            <% if @agent.can_receive_events? %>
+              <p>
+                <b>Last received event:</b>
                 <%= @agent.last_receive_at ? time_ago_in_words(@agent.last_receive_at) + " ago" : "never" %>
                 <%= @agent.last_receive_at ? time_ago_in_words(@agent.last_receive_at) + " ago" : "never" %>
-              <% end %>
-            </p>
+              </p>
+            <% end %>
 
 
-            <p>
-              <b>Event count:</b>
-              <%= link_to @agent.events.count, events_path(:agent => @agent.to_param) %>
-            </p>
+            <% if @agent.can_create_events? %>
+              <p>
+                <b>Events created:</b>
+                <%= link_to @agent.events.count, events_path(:agent => @agent.to_param) %>
+              </p>
+            <% end %>
+
+            <% if @agent.can_receive_events? %>
+              <p>
+                <b>Event sources:</b>
+                <% if @agent.sources.length %>
+                  <%= @agent.sources.map { |source_agent| link_to(source_agent.name, agent_path(source_agent)) }.to_sentence.html_safe %>
+                <% else %>
+                  None
+                <% end %>
+              </p>
+            <% end %>
+
+            <% if @agent.can_create_events? %>
+              <p>
+                <b>Event receivers:</b>
+                <% if @agent.receivers.length %>
+                  <%= @agent.receivers.map { |receiver_agent| link_to(receiver_agent.name, agent_path(receiver_agent)) }.to_sentence.html_safe %>
+                <% else %>
+                  None
+                <% end %>
+              </p>
+            <% end %>
 
 
             <p>
             <p>
               <b>Working:</b>
               <b>Working:</b>

+ 4 - 0
app/views/layouts/_navigation.html.erb

@@ -42,6 +42,10 @@
         <% end %>
         <% end %>
       </li>
       </li>
 
 
+      <li>
+        <%= link_to 'About', 'https://github.com/cantino/huginn', :tabindex => "-1" %>
+      </li>
+
       <li>
       <li>
         <% if user_signed_in? %>
         <% if user_signed_in? %>
           <%= link_to 'Logout', destroy_user_session_path, :method => :delete, :tabindex => "-1" %>
           <%= link_to 'Logout', destroy_user_session_path, :method => :delete, :tabindex => "-1" %>

+ 15 - 5
spec/models/agent_spec.rb

@@ -114,13 +114,23 @@ describe Agent do
     end
     end
 
 
     describe "#create_event" do
     describe "#create_event" do
+      before do
+        @checker = Agents::SomethingSource.new(:name => "something")
+        @checker.user = users(:bob)
+        @checker.save!
+      end
+
       it "should use the checker's user" do
       it "should use the checker's user" do
-        checker = Agents::SomethingSource.new(:name => "something")
-        checker.user = users(:bob)
-        checker.save!
+        @checker.check
+        Event.last.user.should == @checker.user
+      end
 
 
-        checker.check
-        Event.last.user.should == checker.user
+      it "should log an error if the Agent has been marked with 'cannot_create_events!'" do
+        mock(@checker).can_create_events? { false }
+        lambda {
+          @checker.check
+        }.should_not change { Event.count }
+        @checker.logs.first.message.should =~ /cannot create events/i
       end
       end
     end
     end
 
 

+ 5 - 1
vendor/assets/stylesheets/jquery.json-editor.css.scss

@@ -52,8 +52,12 @@
     display: block;
     display: block;
     float: right;
     float: right;
     text-decoration: none;
     text-decoration: none;
-    padding-left: 5px;
+    padding: 0 5px;
     border: 0 !important;
     border: 0 !important;
     color: blue;
     color: blue;
+
+    &:hover {
+      background-color: #bbb;
+    }
   }
   }
 }
 }