Permalink
Browse files

Initial commit

  • Loading branch information...
M7 committed Apr 24, 2012
1 parent 8aef903 commit 2fee23410bb1e71e8d82f0e805d79711747b0561
Showing with 2,394 additions and 66 deletions.
  1. +24 −0 .gitignore
  2. +55 −0 .rvmrc
  3. +58 −0 Gemfile
  4. +7 −0 Rakefile
  5. BIN app/assets/images/rails.png
  6. +15 −0 app/assets/javascripts/application.js
  7. +3 −0 app/assets/javascripts/tasks.js.coffee
  8. +3 −0 app/assets/javascripts/whenbot.js.coffee
  9. +13 −0 app/assets/stylesheets/application.css
  10. +3 −0 app/assets/stylesheets/tasks.css.scss
  11. +3 −0 app/assets/stylesheets/whenbot.css.scss
  12. +3 −0 app/controllers/application_controller.rb
  13. +8 −0 app/controllers/tasks_controller.rb
  14. +31 −0 app/controllers/whenbot_controller.rb
  15. +2 −0 app/helpers/application_helper.rb
  16. +2 −0 app/helpers/tasks_helper.rb
  17. +2 −0 app/helpers/whenbot_helper.rb
  18. 0 app/mailers/.gitkeep
  19. 0 app/models/.gitkeep
  20. +7 −0 app/models/action.rb
  21. +4 −0 app/models/authentication.rb
  22. +21 −0 app/models/task.rb
  23. +96 −0 app/models/trigger.rb
  24. +14 −0 app/views/layouts/application.html.erb
  25. +5 −0 app/views/tasks/_channels.html.erb
  26. +2 −0 app/views/tasks/index.html.erb
  27. +5 −0 app/views/tasks/new.html.erb
  28. +4 −0 config.ru
  29. +60 −0 config/application.rb
  30. +6 −0 config/boot.rb
  31. +60 −0 config/database.yml.example
  32. +5 −0 config/environment.rb
  33. +37 −0 config/environments/development.rb
  34. +67 −0 config/environments/production.rb
  35. +37 −0 config/environments/test.rb
  36. +7 −0 config/initializers/backtrace_silencers.rb
  37. +15 −0 config/initializers/inflections.rb
  38. +5 −0 config/initializers/mime_types.rb
  39. +18 −0 config/initializers/require_lib_files.rb
  40. +7 −0 config/initializers/secret_token.rb
  41. +8 −0 config/initializers/session_store.rb
  42. +7 −0 config/initializers/whenbot.rb
  43. +14 −0 config/initializers/wrap_parameters.rb
  44. +5 −0 config/locales/en.yml
  45. +65 −0 config/routes.rb
  46. +24 −0 db/migrate/20120419221210_create_triggers.rb
  47. +18 −0 db/migrate/20120419230901_create_actions.rb
  48. +12 −0 db/migrate/20120419233318_create_authentications.rb
  49. +13 −0 db/migrate/20120419234122_create_tasks.rb
  50. +71 −0 db/schema.rb
  51. +7 −0 db/seeds.rb
  52. +2 −0 doc/README_FOR_APP
  53. +0 −8 factories/users.rb
  54. 0 lib/assets/.gitkeep
  55. 0 lib/tasks/.gitkeep
  56. +104 −0 lib/whenbot.rb
  57. +5 −0 lib/whenbot/channel.rb
  58. +25 −0 lib/whenbot/channels/developer/actions/do_some_event.rb
  59. +14 −0 lib/whenbot/channels/developer/service.rb
  60. +220 −0 lib/whenbot/channels/developer/triggers/sample_search.rb
  61. +11 −0 lib/whenbot/channels/twitter/service.rb
  62. +56 −0 lib/whenbot/channels/twitter/triggers/new_tweet_from.rb
  63. +19 −0 lib/whenbot/trigger.rb
  64. +3 −0 lib/whenbot/version.rb
  65. 0 log/.gitkeep
  66. +26 −0 public/404.html
  67. +26 −0 public/422.html
  68. +25 −0 public/500.html
  69. 0 public/favicon.ico
  70. +241 −0 public/index.html
  71. +5 −0 public/robots.txt
  72. +6 −0 script/rails
  73. +0 −58 spec/models/action_spec.rb
  74. +13 −0 test/factories/actions.rb
  75. +8 −0 test/factories/authentications.rb
  76. +13 −0 test/factories/tasks.rb
  77. +36 −0 test/factories/triggers.rb
  78. 0 test/functional/.gitkeep
  79. +14 −0 test/functional/tasks_controller_test.rb
  80. +37 −0 test/functional/whenbot_controller_test.rb
  81. 0 test/integration/.gitkeep
  82. +18 −0 test/integration/task_flows_test.rb
  83. +12 −0 test/performance/browsing_test.rb
  84. +39 −0 test/test_helper.rb
  85. 0 test/unit/.gitkeep
  86. +7 −0 test/unit/action_test.rb
  87. +7 −0 test/unit/authentication_test.rb
  88. +4 −0 test/unit/helpers/tasks_helper_test.rb
  89. +4 −0 test/unit/helpers/whenbot_helper_test.rb
  90. +46 −0 test/unit/task_test.rb
  91. +128 −0 test/unit/trigger_test.rb
  92. +127 −0 test/unit/triggers/sample_search_test.rb
  93. +107 −0 test/unit/triggers/trigger_conformance_test.rb
  94. +28 −0 test/unit/whenbot_test.rb
  95. 0 vendor/assets/javascripts/.gitkeep
  96. 0 vendor/assets/stylesheets/.gitkeep
  97. 0 vendor/plugins/.gitkeep
View
@@ -0,0 +1,24 @@
+# See http://help.github.com/ignore-files/ for more about ignoring files.
+#
+# If you find yourself ignoring temporary files generated by your text editor
+# or operating system, you probably want to add a global ignore instead:
+# git config --global core.excludesfile ~/.gitignore_global
+
+# Ignore bundler config
+/.bundle
+
+# Ignore the default SQLite database.
+/db/*.sqlite3
+
+# Ignore all logfiles and tempfiles.
+/log/*.log
+/tmp
+
+# This code will be Open Source, so don't include files with sensitive data
+/config/database.yml
+
+# Ignore .watchr file
+/.watchr
+
+# Random files to ignore
+/lib/whenbot/old_trigger.rb
View
55 .rvmrc
@@ -0,0 +1,55 @@
+#!/usr/bin/env bash
+
+# This is an RVM Project .rvmrc file, used to automatically load the ruby
+# development environment upon cd'ing into the directory
+
+# First we specify our desired <ruby>[@<gemset>], the @gemset name is optional.
+environment_id="ruby-1.9.3-p125@whenbot"
+
+#
+# Uncomment following line if you want options to be set only for given project.
+#
+# PROJECT_JRUBY_OPTS=( --1.9 )
+
+#
+# First we attempt to load the desired environment directly from the environment
+# file. This is very fast and efficient compared to running through the entire
+# CLI and selector. If you want feedback on which environment was used then
+# insert the word 'use' after --create as this triggers verbose mode.
+#
+if [[ -d "${rvm_path:-$HOME/.rvm}/environments" \
+ && -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]
+then
+ \. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
+
+ if [[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]]
+ then
+ . "${rvm_path:-$HOME/.rvm}/hooks/after_use"
+ fi
+else
+ # If the environment file has not yet been created, use the RVM CLI to select.
+ if ! rvm --create "$environment_id"
+ then
+ echo "Failed to create RVM environment '${environment_id}'."
+ exit 1
+ fi
+fi
+
+#
+# If you use an RVM gemset file to install a list of gems (*.gems), you can have
+# it be automatically loaded. Uncomment the following and adjust the filename if
+# necessary.
+#
+# filename=".gems"
+# if [[ -s "$filename" ]]
+# then
+# rvm gemset import "$filename" | grep -v already | grep -v listed | grep -v complete | sed '/^$/d'
+# fi
+
+# If you use bundler, this might be useful to you:
+# if command -v bundle && [[ -s Gemfile ]]
+# then
+# bundle install
+# fi
+
+
View
58 Gemfile
@@ -0,0 +1,58 @@
+source 'https://rubygems.org'
+
+gem 'rails', '3.2.3'
+
+# Bundle edge Rails instead:
+# gem 'rails', :git => 'git://github.com/rails/rails.git'
+
+gem 'pg'
+
+
+# Gems used only for assets and not required
+# in production environments by default.
+group :assets do
+ gem 'sass-rails', '~> 3.2.3'
+ gem 'coffee-rails', '~> 3.2.1'
+
+ # See https://github.com/sstephenson/execjs#readme for more supported runtimes
+ gem 'therubyracer', :platform => :ruby
+
+ gem 'uglifier', '>= 1.0.3'
+end
+
+gem 'jquery-rails'
+
+gem 'heroku'
+
+group :test, :development do
+ gem 'awesome_print'
+ gem 'factory_girl_rails'
+end
+
+group :development do
+ #gem 'ruby-debug19', :require => 'ruby-debug' # To use debugger
+ gem 'rails-footnotes', '>= 3.7'
+end
+
+group :test do
+ gem 'test-unit' # not bundled with ruby 1.9
+ gem 'capybara', :git => 'git://github.com/jnicklas/capybara.git' # For #has_text?
+ gem 'database_cleaner' # For Capybara. See test_helper.rb for details
+ gem 'mocha', :require => false
+ gem 'shoulda'
+end
+
+# To use ActiveModel has_secure_password
+# gem 'bcrypt-ruby', '~> 3.0.0'
+
+# To use Jbuilder templates for JSON
+# gem 'jbuilder'
+
+# Use unicorn as the app server
+# gem 'unicorn'
+
+# Deploy with Capistrano
+# gem 'capistrano'
+
+# To use debugger
+# gem 'ruby-debug19', :require => 'ruby-debug'
View
@@ -0,0 +1,7 @@
+#!/usr/bin/env rake
+# Add your own tasks in files placed in lib/tasks ending in .rake,
+# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
+
+require File.expand_path('../config/application', __FILE__)
+
+Whenbot::Application.load_tasks
View
Binary file not shown.
@@ -0,0 +1,15 @@
+// This is a manifest file that'll be compiled into application.js, which will include all the files
+// listed below.
+//
+// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
+// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
+//
+// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
+// the compiled file.
+//
+// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
+// GO AFTER THE REQUIRES BELOW.
+//
+//= require jquery
+//= require jquery_ujs
+//= require_tree .
@@ -0,0 +1,3 @@
+# Place all the behaviors and hooks related to the matching controller here.
+# All this logic will automatically be available in application.js.
+# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
@@ -0,0 +1,3 @@
+# Place all the behaviors and hooks related to the matching controller here.
+# All this logic will automatically be available in application.js.
+# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
@@ -0,0 +1,13 @@
+/*
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
+ * listed below.
+ *
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
+ *
+ * You're free to add application-wide styles to this file and they'll appear at the top of the
+ * compiled file, but it's generally better to create a new file per style scope.
+ *
+ *= require_self
+ *= require_tree .
+*/
@@ -0,0 +1,3 @@
+// Place all the styles related to the tasks controller here.
+// They will automatically be included in application.css.
+// You can use Sass (SCSS) here: http://sass-lang.com/
@@ -0,0 +1,3 @@
+// Place all the styles related to the Whenbot controller here.
+// They will automatically be included in application.css.
+// You can use Sass (SCSS) here: http://sass-lang.com/
@@ -0,0 +1,3 @@
+class ApplicationController < ActionController::Base
+ protect_from_forgery
+end
@@ -0,0 +1,8 @@
+class TasksController < ApplicationController
+ def index
+ end
+
+ def new
+ # ==== One-liner 12 ====
+ end
+end
@@ -0,0 +1,31 @@
+class WhenbotController < ApplicationController
+
+ # /whenbot/:channel/:trigger/callback
+ def callback
+
+ # ==== One-liner 13 ====
+ # ==== One-liner 14 ====
+
+ if response[:head_only]
+ # ==== One-liner 15 ====
+ else
+ render response[:type] => response[:body],
+ :status => response[:status],
+ :layout => false
+ end
+ end
+
+ private
+
+ def validate_response(response)
+ # ==== One-liner 16 ====
+ response[:head_only] ||= response[:body] ? false : true
+ response[:status] ||= :ok
+ response[:type] ||= :json
+ response[:headers] ||= ''
+ response[:body] ||= 'Success'
+ # ==== One-liner 17 ====
+ end
+
+
+end
@@ -0,0 +1,2 @@
+module ApplicationHelper
+end
@@ -0,0 +1,2 @@
+module TasksHelper
+end
@@ -0,0 +1,2 @@
+module WhenbotHelper
+end
View
No changes.
View
No changes.
View
@@ -0,0 +1,7 @@
+class Action < ActiveRecord::Base
+ belongs_to :task
+
+ serialize :parameters, Hash
+ serialize :extra_data, Hash
+ attr_accessible :channel, :action, :parameters, :active
+end
@@ -0,0 +1,4 @@
+class Authentication < ActiveRecord::Base
+ serialize :parameters, Hash
+ attr_accessible :channel, :parameters
+end
View
@@ -0,0 +1,21 @@
+class Task < ActiveRecord::Base
+ # ==== One-liner 18 ====
+ # ==== One-liner 19 ====
+
+ accepts_nested_attributes_for :triggers, :actions
+
+ # ==== One-liner 20 ====
+
+ #
+ # Handles calling the appropriate Trigger's #callback method,
+ # saves the match data to the table, and runs the Action(s) if
+ # its conditions are met.
+ #
+ def self.handle_callback(channel, trigger, params, headers, body)
+ triggers, trigger_ids = Trigger.triggers_for(channel, trigger)
+ returned_triggers, response = Whenbot.relay_callback(channel, trigger, triggers, params, headers, body)
+ # ==== One-liner 21 ====
+ # ==== One-liner 22 ====
+ end
+
+end
View
@@ -0,0 +1,96 @@
+class Trigger < ActiveRecord::Base
+ # ==== One-liner 23 ====
+
+ # ==== One-liner 24 ====
+ # ==== One-liner 25 ====
+ # ==== One-liner 26 ====
+ # ==== One-liner 27 ====
+ # ==== One-liner 28 ====
+ # ==== One-liner 29 ====
+
+
+ #
+ # Returns all active triggers for the requested Channel and Trigger
+ #
+ def self.triggers_for(channel, trigger)
+ records = where("channel = ? AND trigger = ?", channel.to_s.camelize, trigger.to_s.camelize).
+ select([:id, :channel, :trigger, :parameters, :match_data, :extra_data, :last_matched]).
+ active
+ convert_for_matching(records)
+ end
+
+ #
+ # Saves triggers that either have their :save or
+ # :matched flag set
+ def self.save_updated_triggers(triggers, trigger_ids)
+ save_updated_hash(triggers, trigger_ids)
+ end
+
+ private
+
+ #
+ # Creates an array of hashes to be passed to the Trigger
+ # via its #callback method. The Trigger will fill in
+ # the array[n][:match_data] if there's a match, and
+ # can use array[n][:extra_data] to store data that
+ # it may need later.
+ #
+ # Another array of ids is returned to keep track of
+ # which records should be updated.
+ #
+ # We do this to avoid passing around actual records.
+ # A Trigger only needs to concern itself with certain
+ # things, and shouldn't be playing with table data.
+ #
+ # Hash Values:
+ #
+ # :save => Signals that the hash was updated and
+ # should be saved
+ # :matched => New match was found, and stored in
+ # :match_data. Data will be saved
+ # even if :save isn't set to true
+ # :parameters => Parameters saved from the user
+ # :match_data => Match data that's saved to be
+ # used by the Action (i.e. the
+ # data to be used by Liquid)
+ # :extra_data => Use this to store any data
+ # you want to receive next time
+ # :last_matched => Time that this Trigger last
+ # had a match.
+ def self.convert_for_matching(records)
+ array = Array.new
+ ids_array = Array.new
+
+ triggers = Array(records)
+ triggers.each do |trigger|
+ hash = Hash.new
+ hash[:save] = false
+ hash[:match_found] = false
+ hash[:parameters] = trigger.parameters || {}
+ hash[:match_data] = trigger.match_data || {}
+ hash[:extra_data] = trigger.extra_data || {}
+ hash[:last_matched] = trigger.last_matched
+ array << hash
+ ids_array << trigger.id
+ end
+ return array, ids_array
+ end
+
+ def self.save_updated_hash(triggers, trigger_ids)
+ triggers.each_with_index do |trigger, index|
+ if trigger[:save] || trigger[:match]
+ record = Trigger.find(trigger_ids[index])
+
+ if trigger[:save]
+ trigger.each_pair do |key, value|
+ record.send("#{key}=", value) if record.respond_to? "#{key}=".to_sym
+ end
+ elsif trigger[:match_found]
+ record.match_data = trigger[:match_data]
+ end
+
+ record.save! if record.changed?
+ end
+ end
+ end
+end
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Whenbot</title>
+ <%= stylesheet_link_tag "application", :media => "all" %>
+ <%= javascript_include_tag "application" %>
+ <%= csrf_meta_tags %>
+</head>
+<body>
+
+<%= yield %>
+
+</body>
+</html>
Oops, something went wrong.

0 comments on commit 2fee234

Please sign in to comment.