Andrew Cantino 11 years ago
parent
commit
f8ee5e3ec4

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

@@ -99,9 +99,12 @@ $(document).ready ->
         $("#logs .spinner").stop(true, true).fadeOut ->
           $("#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
   $("#agent_source_ids").on "change", showEventDescriptions

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

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

+ 1 - 1
app/helpers/application_helper.rb

@@ -11,7 +11,7 @@ module ApplicationHelper
     if agent.working?
       '<span class="label label-success">Yes</span>'.html_safe
     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

+ 22 - 2
app/models/agent.rb

@@ -88,7 +88,11 @@ class Agent < ActiveRecord::Base
   end
 
   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
 
   def validate_schedule
@@ -117,7 +121,7 @@ class Agent < ActiveRecord::Base
   end
 
   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
 
   def default_schedule
@@ -140,6 +144,14 @@ class Agent < ActiveRecord::Base
     !cannot_receive_events?
   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
     if newest_event_id = Event.order("id desc").limit(1).pluck(:id).first
       self.last_checked_event_id = newest_event_id
@@ -169,6 +181,14 @@ class Agent < ActiveRecord::Base
       @default_schedule
     end
 
+    def cannot_create_events!
+      @cannot_create_events = true
+    end
+
+    def cannot_create_events?
+      !!@cannot_create_events
+    end
+
     def cannot_receive_events!
       @cannot_receive_events = true
     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)
     default_schedule "5am"
 
+    cannot_create_events!
+
     description <<-MD
       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

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

@@ -1,6 +1,7 @@
 module Agents
   class PostAgent < Agent
     cannot_be_scheduled!
+    cannot_create_events!
 
     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`)

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

@@ -4,6 +4,7 @@ require 'securerandom'
 module Agents
   class TwilioAgent < Agent
     cannot_be_scheduled!
+    cannot_create_events!
 
     description <<-MD
       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">
     <%= f.label :sources, :class => 'control-label' %>
     <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,
-                   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),
                    {}, { :multiple => true, :size => 5, :class => 'span4 select2' }) %>
       <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'>
         <tr>
           <th>Name</th>
+          <th>Schedule</th>
           <th>Last Check</th>
           <th>Last Event Out</th>
           <th>Last Event In</th>
-          <th>Events</th>
-          <th>Schedule</th>
+          <th>Events Created</th>
           <th>Working?</th>
           <th></th>
         </tr>
 
         <% @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 %>
-                    <%= agent.last_receive_at ? time_ago_in_words(agent.last_receive_at) + " ago" : "never" %>
+                  <%= link_to 'Run', "#", class: "btn btn-mini disabled" %>
                 <% 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 %>
       </table>
 

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

@@ -13,7 +13,7 @@
           <% end %>
           <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>
           <% end %>
           <li><%= link_to '<i class="icon-chevron-left"></i> Back'.html_safe, agents_path %></li>
@@ -29,7 +29,7 @@
                   </li>
                 <% end %>
 
-                <% if @agent.events.count > 0 %>
+                <% if @agent.can_create_events? && @agent.events.count > 0 %>
                   <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" %>
                   </li>
@@ -70,38 +70,60 @@
               <%= @agent.short_type.titleize %>
             </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" %>
-              <% 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" %>
-              <% 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>
               <b>Working:</b>

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

@@ -42,6 +42,10 @@
         <% end %>
       </li>
 
+      <li>
+        <%= link_to 'About', 'https://github.com/cantino/huginn', :tabindex => "-1" %>
+      </li>
+
       <li>
         <% if user_signed_in? %>
           <%= 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
 
     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
-        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
 

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

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