ifd_tools 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (137) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.md +28 -0
  3. data/Rakefile +40 -0
  4. data/app/admin/emergency_messages.rb +33 -0
  5. data/app/admin/notifier_updates.rb +42 -0
  6. data/app/admin/software_updates.rb +42 -0
  7. data/app/admin/users.rb +48 -0
  8. data/app/assets/javascripts/ifd_tools/base.js +4 -0
  9. data/app/assets/javascripts/ifd_tools/fusion_charts.js +361 -0
  10. data/app/assets/stylesheets/ifd_tools/active_admin/_analytics.scss +32 -0
  11. data/app/assets/stylesheets/ifd_tools/active_admin/_cleanup.scss +15 -0
  12. data/app/assets/stylesheets/ifd_tools/active_admin/_footer.scss +87 -0
  13. data/app/assets/stylesheets/ifd_tools/active_admin/_square_admin_buttons.scss +27 -0
  14. data/app/assets/stylesheets/ifd_tools/base.scss +4 -0
  15. data/app/assets/swfs/FCF_Area2D.swf +0 -0
  16. data/app/assets/swfs/usa_map.swf +0 -0
  17. data/app/controllers/ifd_tools/application_controller.rb +4 -0
  18. data/app/helpers/ifd_tools/application_helper.rb +30 -0
  19. data/app/models/ifd_tools/emergency_message.rb +27 -0
  20. data/app/models/ifd_tools/notifier_update.rb +28 -0
  21. data/app/models/ifd_tools/software_update.rb +28 -0
  22. data/app/models/ifd_tools/tracking/application_event.rb +6 -0
  23. data/app/models/ifd_tools/tracking/event.rb +51 -0
  24. data/app/models/ifd_tools/tracking.rb +7 -0
  25. data/app/uploaders/software_uploader.rb +18 -0
  26. data/app/views/admin/customers/_trend.html.haml +7 -0
  27. data/app/views/admin/customers/_trend_info_sidebar.html.haml +11 -0
  28. data/app/views/admin/customers/demographic_data.builder +11 -0
  29. data/app/views/admin/customers/events_data.builder +6 -0
  30. data/app/views/admin/customers/filter_events.js.erb +6 -0
  31. data/app/views/admin/customers/trends.html.haml +11 -0
  32. data/app/views/admin/dashboard/_line_graph.html.haml +11 -0
  33. data/app/views/admin/dashboard/_usa_map.html.haml +2 -0
  34. data/app/views/admin/emergency_messages/_form.html.haml +6 -0
  35. data/app/views/admin/notifier_updates/_form.html.haml +9 -0
  36. data/app/views/admin/shared/_footer.html.haml +6 -0
  37. data/app/views/admin/software_updates/_form.html.haml +9 -0
  38. data/app/views/admin/users/_form.html.haml +9 -0
  39. data/app/views/api/emergency_messages.builder +12 -0
  40. data/app/views/api/notifier_updates.builder +15 -0
  41. data/app/views/api/software_updates.builder +15 -0
  42. data/app/views/api/track.builder +6 -0
  43. data/app/views/layouts/ifd_tools/application.html.erb +14 -0
  44. data/config/routes.rb +2 -0
  45. data/db/migrate/20121010183004_create_ifd_tools_emergency_messages.rb +11 -0
  46. data/db/migrate/20121011150939_create_ifd_tools_notifier_updates.rb +14 -0
  47. data/db/migrate/20121011151124_create_ifd_tools_software_updates.rb +14 -0
  48. data/db/migrate/20121011205911_devise_create_users.rb +57 -0
  49. data/db/migrate/20121012123505_create_customers.rb +52 -0
  50. data/db/migrate/20121012133303_create_ifd_tools_tracking_events.rb +14 -0
  51. data/lib/generators/ifd_tools/install/USAGE +5 -0
  52. data/lib/generators/ifd_tools/install/install_generator.rb +153 -0
  53. data/lib/generators/ifd_tools/install/templates/admin/customers.rb +108 -0
  54. data/lib/generators/ifd_tools/install/templates/admin/dashboard.rb +47 -0
  55. data/lib/generators/ifd_tools/install/templates/assets/active_admin.css.scss +7 -0
  56. data/lib/generators/ifd_tools/install/templates/assets/active_admin.js +2 -0
  57. data/lib/generators/ifd_tools/install/templates/assets/application.css.scss +46 -0
  58. data/lib/generators/ifd_tools/install/templates/assets/application.js +2 -0
  59. data/lib/generators/ifd_tools/install/templates/assets/ckeditor.js.coffee +13 -0
  60. data/lib/generators/ifd_tools/install/templates/capistrano/Capfile +5 -0
  61. data/lib/generators/ifd_tools/install/templates/capistrano/deploy/production.rb +2 -0
  62. data/lib/generators/ifd_tools/install/templates/capistrano/deploy/staging.rb +2 -0
  63. data/lib/generators/ifd_tools/install/templates/capistrano/deploy.rb +50 -0
  64. data/lib/generators/ifd_tools/install/templates/config/en.yml +17 -0
  65. data/lib/generators/ifd_tools/install/templates/config/ifd_tools.rb +4 -0
  66. data/lib/generators/ifd_tools/install/templates/config/schedule.rb.erb +28 -0
  67. data/lib/generators/ifd_tools/install/templates/controllers/api_controller.rb +8 -0
  68. data/lib/generators/ifd_tools/install/templates/controllers/application_controller.rb +19 -0
  69. data/lib/generators/ifd_tools/install/templates/controllers/customer_session_controller.rb +39 -0
  70. data/lib/generators/ifd_tools/install/templates/foreman/Procfile +2 -0
  71. data/lib/generators/ifd_tools/install/templates/layouts/application.html.haml +29 -0
  72. data/lib/generators/ifd_tools/install/templates/layouts/application_logged_out.html.haml +21 -0
  73. data/lib/generators/ifd_tools/install/templates/models/ability.rb +23 -0
  74. data/lib/generators/ifd_tools/install/templates/models/customer.rb +60 -0
  75. data/lib/generators/ifd_tools/install/templates/models/settings.rb +5 -0
  76. data/lib/generators/ifd_tools/install/templates/models/user.rb +31 -0
  77. data/lib/generators/ifd_tools/install/templates/settings/application.yml +16 -0
  78. data/lib/generators/ifd_tools/install/templates/views/customers/_form.html.haml +8 -0
  79. data/lib/ifd_tools/active_admin/base.rb +18 -0
  80. data/lib/ifd_tools/api_controller/emergency_messages.rb +9 -0
  81. data/lib/ifd_tools/api_controller/notifier_updates.rb +9 -0
  82. data/lib/ifd_tools/api_controller/software_updates.rb +9 -0
  83. data/lib/ifd_tools/api_controller/tracking.rb +44 -0
  84. data/lib/ifd_tools/api_controller_extensions.rb +18 -0
  85. data/lib/ifd_tools/configure.rb +27 -0
  86. data/lib/ifd_tools/date_time_additions.rb +11 -0
  87. data/lib/ifd_tools/engine.rb +17 -0
  88. data/lib/ifd_tools/states.rb +59 -0
  89. data/lib/ifd_tools/tracking/customer_tracking.rb +143 -0
  90. data/lib/ifd_tools/tracking/trackable.rb +28 -0
  91. data/lib/ifd_tools/validations/phone.rb +17 -0
  92. data/lib/ifd_tools/version.rb +3 -0
  93. data/lib/ifd_tools.rb +26 -0
  94. data/lib/tasks/ifd_tools_tasks.rake +2 -0
  95. data/test/dummy/README.rdoc +261 -0
  96. data/test/dummy/Rakefile +7 -0
  97. data/test/dummy/app/assets/javascripts/application.js +15 -0
  98. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  99. data/test/dummy/app/controllers/application_controller.rb +3 -0
  100. data/test/dummy/app/helpers/application_helper.rb +2 -0
  101. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  102. data/test/dummy/config/application.rb +59 -0
  103. data/test/dummy/config/boot.rb +10 -0
  104. data/test/dummy/config/database.yml +25 -0
  105. data/test/dummy/config/environment.rb +5 -0
  106. data/test/dummy/config/environments/development.rb +37 -0
  107. data/test/dummy/config/environments/production.rb +67 -0
  108. data/test/dummy/config/environments/test.rb +37 -0
  109. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  110. data/test/dummy/config/initializers/inflections.rb +15 -0
  111. data/test/dummy/config/initializers/mime_types.rb +5 -0
  112. data/test/dummy/config/initializers/secret_token.rb +7 -0
  113. data/test/dummy/config/initializers/session_store.rb +8 -0
  114. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  115. data/test/dummy/config/locales/en.yml +5 -0
  116. data/test/dummy/config/routes.rb +4 -0
  117. data/test/dummy/config.ru +4 -0
  118. data/test/dummy/db/development.sqlite3 +0 -0
  119. data/test/dummy/db/schema.rb +24 -0
  120. data/test/dummy/log/development.log +15 -0
  121. data/test/dummy/public/404.html +26 -0
  122. data/test/dummy/public/422.html +26 -0
  123. data/test/dummy/public/500.html +25 -0
  124. data/test/dummy/public/favicon.ico +0 -0
  125. data/test/dummy/script/rails +6 -0
  126. data/test/fixtures/ifd_tools/emergency_messages.yml +11 -0
  127. data/test/fixtures/ifd_tools/notifier_updates.yml +17 -0
  128. data/test/fixtures/ifd_tools/software_updates.yml +17 -0
  129. data/test/fixtures/ifd_tools/tracking/events.yml +17 -0
  130. data/test/ifd_tools_test.rb +7 -0
  131. data/test/integration/navigation_test.rb +10 -0
  132. data/test/test_helper.rb +15 -0
  133. data/test/unit/ifd_tools/emergency_message_test.rb +9 -0
  134. data/test/unit/ifd_tools/notifier_update_test.rb +9 -0
  135. data/test/unit/ifd_tools/software_update_test.rb +9 -0
  136. data/test/unit/ifd_tools/tracking/event_test.rb +9 -0
  137. metadata +464 -0
@@ -0,0 +1,29 @@
1
+ %html
2
+ %head
3
+ %title= Settings.app_name
4
+ = stylesheet_link_tag "application", media: "all"
5
+ = javascript_include_tag "application"
6
+ = favicon_link_tag
7
+ = csrf_meta_tags
8
+
9
+ %body(class="active_admin logged_in #{params[:controller].gsub('/', '_')} #{params[:action]}")
10
+
11
+ #wrapper
12
+ #header.header
13
+
14
+ %h1#site_title.site_title= @page_title || Settings.app_header_name
15
+ %p#utility_nav.header-item
16
+ /= link_to "Sign Out", destroy_customer_session_path, method: :delete, title: "Sign Out"
17
+
18
+ .flashes
19
+ - flash.each do |type, message|
20
+ %div(class="flash flash_#{type}")= message
21
+
22
+ #active_admin_content.without_sidebar
23
+ #main_content_wrapper
24
+ = yield
25
+ .clearBoth
26
+
27
+ #footer
28
+ #site_footer
29
+ = yield :footer
@@ -0,0 +1,21 @@
1
+ %html
2
+ %head
3
+ %title= Settings.app_name
4
+ = stylesheet_link_tag "application", media: "all"
5
+ = javascript_include_tag "application"
6
+ = csrf_meta_tags
7
+
8
+ %body(class="logged_out #{params[:controller].gsub('/', '_')} #{params[:action]}")
9
+
10
+ #wrapper
11
+ #header.header
12
+ %h1#site_title= @page_title || Settings.app_header_name
13
+ #content_wrapper
14
+ - flash.each do |type, message|
15
+ %div(class="flash flash_#{type}")= message
16
+
17
+ #active_admin_content
18
+ = yield
19
+
20
+ #footer
21
+ = yield :footer
@@ -0,0 +1,23 @@
1
+ class Ability
2
+ include CanCan::Ability
3
+
4
+ def initialize(user)
5
+
6
+ user ||= User.new
7
+
8
+ can :manage, :all
9
+ cannot [:create, :new], Customer
10
+
11
+ unless user.super_admin?
12
+
13
+ # Only manage regular accounts
14
+ cannot :manage, User
15
+ can :manage, User, role: %w(admin)
16
+
17
+ # Cannot manage some other sensitive items
18
+ cannot :manage, [IfdTools::SoftwareUpdate, IfdTools::EmergencyMessage, IfdTools::NotifierUpdate]
19
+
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,60 @@
1
+ class Customer < ActiveRecord::Base
2
+
3
+ Statuses = %w(active banned pending)
4
+
5
+ devise :database_authenticatable, :recoverable, :rememberable, :trackable, :validatable, :token_authenticatable, :confirmable
6
+
7
+ has_many :tracking_events, :class_name => 'IfdTools::Tracking::Event', dependent: :destroy
8
+
9
+ # Setup accessible (or protected) attributes for your model
10
+ attr_accessible :email, :password, :password_confirmation, :remember_me, :first_name, :last_name, :phone, :state, :platform
11
+
12
+ validates :first_name, :last_name, :email, :state, presence: true
13
+ validates_phone :phone, presence: true
14
+
15
+ default_scope order("lower(first_name) asc, lower(last_name) asc")
16
+
17
+ Statuses.each do |s|
18
+ scope s.to_sym, where(status: s)
19
+ define_method("#{s}?") { status == s }
20
+ end
21
+
22
+ scope :unconfirmed, where(confirmed_at: nil)
23
+ scope :top_users, includes(:tracking_events).group("ifd_tools_tracking_events.customer_id").reorder("count(ifd_tools_tracking_events.customer_id) desc, lower(first_name) asc, lower(last_name) asc")
24
+
25
+ before_save :ensure_authentication_token
26
+ before_save :sanitize_phone
27
+
28
+ acts_as_url :full_name, limit: 100
29
+
30
+ def full_name
31
+ "#{first_name} #{last_name}"
32
+ end
33
+
34
+ def display_name
35
+ full_name
36
+ end
37
+
38
+ def to_param
39
+ url
40
+ end
41
+
42
+ def activate!
43
+ update_attribute :status, "active"
44
+ end
45
+
46
+ def deactivate!
47
+ update_attribute :status, "banned"
48
+ end
49
+
50
+ def active?
51
+ status == "active"
52
+ end
53
+
54
+ private
55
+
56
+ def sanitize_phone
57
+ self.phone = phone.gsub(/[^0-9]*/, '')
58
+ end
59
+
60
+ end
@@ -0,0 +1,5 @@
1
+ class Settings < Settingslogic
2
+ source "#{Rails.root}/config/application.yml"
3
+ namespace Rails.env
4
+ load!
5
+ end
@@ -0,0 +1,31 @@
1
+ class User < ActiveRecord::Base
2
+
3
+ Roles = %w(admin super_admin)
4
+
5
+ devise :database_authenticatable, :recoverable, :rememberable, :trackable, :validatable
6
+ attr_accessible :email, :password, :password_confirmation, :remember_me, :first_name, :last_name, :time_zone, :role
7
+
8
+ validates :first_name, :last_name, presence: true
9
+
10
+ default_scope order("lower(first_name) asc, lower(last_name) asc")
11
+
12
+ after_create { |admin| admin.delay.send_reset_password_instructions }
13
+
14
+ def full_name
15
+ "#{first_name} #{last_name}"
16
+ end
17
+
18
+ def display_name
19
+ full_name
20
+ end
21
+
22
+ Roles.each do |r|
23
+ define_method("#{r}?") { role == r }
24
+ scope r.to_sym, where(role: r)
25
+ end
26
+
27
+ def password_required?
28
+ new_record? ? false : super
29
+ end
30
+
31
+ end
@@ -0,0 +1,16 @@
1
+ defaults: &defaults
2
+ notifications_email: "notifications@domain.com"
3
+ app_name: "Name of CMS"
4
+ app_header_name: "Name of App Header"
5
+
6
+ development:
7
+ <<: *defaults
8
+
9
+ test:
10
+ <<: *defaults
11
+
12
+ staging:
13
+ <<: *defaults
14
+
15
+ production:
16
+ <<: *defaults
@@ -0,0 +1,8 @@
1
+ = semantic_form_for [:admin, @customer] do |f|
2
+ = f.inputs "Customer Information" do
3
+ = f.input :first_name, label: "First Name"
4
+ = f.input :last_name, label: "Last Name"
5
+ = f.input :email
6
+ = f.input :phone, input_html: { value: phone_number(@customer.phone) }
7
+ = f.input :state, as: :select, collection: IfdTools::States::all.invert
8
+ = f.buttons
@@ -0,0 +1,18 @@
1
+ module ActiveAdmin
2
+ module Views
3
+ module Pages
4
+ class Base# < Arbre::HTML::Document
5
+
6
+ private
7
+
8
+ # Renders the content for the footer
9
+ def build_footer
10
+ div :id => "footer" do
11
+ text_node(render 'admin/shared/footer')
12
+ end
13
+ end
14
+
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,9 @@
1
+ module IfdTools
2
+ module ApiController
3
+ module EmergencyMessages
4
+ def emergency_messages
5
+ @messages = IfdTools::EmergencyMessage.active.first
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module IfdTools
2
+ module ApiController
3
+ module NotifierUpdates
4
+ def notifier_updates
5
+ @notifier_update = NotifierUpdate.current.first
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module IfdTools
2
+ module ApiController
3
+ module SoftwareUpdates
4
+ def software_updates
5
+ @software_update = SoftwareUpdate.current.first
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,44 @@
1
+ module IfdTools
2
+ module ApiController
3
+ module Tracking
4
+
5
+ # Used to record events from the application
6
+ #
7
+ # - trackable_type: ("application_event", "product_event") should be the last part of a model name, ie "IfdTools::Tracking::ProductEvent" => "product_event"
8
+ # - trackable_id: integer pk (null if trackable_type == "application")
9
+ # #
10
+ def track
11
+
12
+ begin
13
+
14
+ unless params[:type].present? && params[:id].present?
15
+ @error = "Missing 'type' or 'id' parameter"
16
+ render status: :unprocessable_entity and return
17
+ end
18
+
19
+ case params[:type]
20
+ when "application_event"
21
+ @event = IfdTools::Tracking::ApplicationEvent.new
22
+
23
+ else
24
+ @event = "ifd_tools/tracking/#{params[:type]}".camelize.constantize.new
25
+ @event.assign_trackable_item_by_id(params[:id])
26
+
27
+ end
28
+
29
+ unless @event.nil?
30
+ @event.ip_address = request.remote_ip
31
+ @event.customer = current_customer
32
+ @event.platform = IfdTools::Tracking::Event.platform_for_request(request)
33
+ @event.save!
34
+ end
35
+
36
+ rescue Exception => e
37
+ @error = e.message
38
+ render status: :unprocessable_entity
39
+ end
40
+ end
41
+
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,18 @@
1
+ require 'ifd_tools/api_controller/emergency_messages'
2
+ require 'ifd_tools/api_controller/software_updates'
3
+ require 'ifd_tools/api_controller/notifier_updates'
4
+ require 'ifd_tools/api_controller/tracking'
5
+
6
+ module IfdTools
7
+ module ApiControllerExtensions
8
+ extend ActiveSupport::Concern
9
+
10
+ included do
11
+ include IfdTools::ApiController::EmergencyMessages
12
+ include IfdTools::ApiController::SoftwareUpdates
13
+ include IfdTools::ApiController::NotifierUpdates
14
+ include IfdTools::ApiController::Tracking
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,27 @@
1
+ module IfdTools
2
+ class Configure
3
+ class << self
4
+
5
+ def dashboard_graph_color=(c)
6
+ @@dashboard_graph_color = c
7
+ end
8
+
9
+ def dashboard_graph_color
10
+ @@dashboard_graph_color ||= "AFD8F8"
11
+ end
12
+
13
+ def dashboard_graph_main_color=(c)
14
+ @@dashboard_graph_main_color = c
15
+ end
16
+
17
+ def dashboard_graph_main_color
18
+ @@dashboard_graph_main_color ||= "114B78"
19
+ end
20
+
21
+ def setup(&block)
22
+ block.call(self)
23
+ end
24
+
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,11 @@
1
+ class Time
2
+ def humanize
3
+ strftime "%b %d, %Y %I:%M%p"
4
+ end
5
+ end
6
+
7
+ class Date
8
+ def humanize
9
+ strftime "%b %d, %Y"
10
+ end
11
+ end
@@ -0,0 +1,17 @@
1
+ module IfdTools
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace IfdTools
4
+
5
+ initializer "ifd_tools.load_static_assets" do |app|
6
+ app.middleware.use ::ActionDispatch::Static, "#{root}/public"
7
+ end
8
+
9
+ initializer "ifd_tools.active_admin" do |app|
10
+ ActiveAdmin::Event.subscribe ActiveAdmin::Application::BeforeLoadEvent do |app|
11
+ require 'ifd_tools/tracking/customer_tracking'
12
+ app.load_paths << File.expand_path( File.dirname(__FILE__) + "../../../app/admin" )
13
+ end
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,59 @@
1
+ module IfdTools
2
+ module States
3
+ def self.all
4
+ state_abbr = {
5
+ 'AL' => 'Alabama',
6
+ 'AK' => 'Alaska',
7
+ 'AZ' => 'Arizona',
8
+ 'AR' => 'Arkansas',
9
+ 'CA' => 'California',
10
+ 'CO' => 'Colorado',
11
+ 'CT' => 'Connecticut',
12
+ 'DE' => 'Delaware',
13
+ 'DC' => 'District of Columbia',
14
+ 'FL' => 'Florida',
15
+ 'GA' => 'Georgia',
16
+ 'HI' => 'Hawaii',
17
+ 'ID' => 'Idaho',
18
+ 'IL' => 'Illinois',
19
+ 'IN' => 'Indiana',
20
+ 'IA' => 'Iowa',
21
+ 'KS' => 'Kansas',
22
+ 'KY' => 'Kentucky',
23
+ 'LA' => 'Louisiana',
24
+ 'ME' => 'Maine',
25
+ 'MD' => 'Maryland',
26
+ 'MA' => 'Massachusetts',
27
+ 'MI' => 'Michigan',
28
+ 'MN' => 'Minnesota',
29
+ 'MS' => 'Mississippi',
30
+ 'MO' => 'Missouri',
31
+ 'MT' => 'Montana',
32
+ 'NE' => 'Nebraska',
33
+ 'NV' => 'Nevada',
34
+ 'NH' => 'New Hampshire',
35
+ 'NJ' => 'New Jersey',
36
+ 'NM' => 'New Mexico',
37
+ 'NY' => 'New York',
38
+ 'NC' => 'North Carolina',
39
+ 'ND' => 'North Dakota',
40
+ 'OH' => 'Ohio',
41
+ 'OK' => 'Oklahoma',
42
+ 'OR' => 'Oregon',
43
+ 'PA' => 'Pennsylvania',
44
+ 'RI' => 'Rhode Island',
45
+ 'SC' => 'South Carolina',
46
+ 'SD' => 'South Dakota',
47
+ 'TN' => 'Tennessee',
48
+ 'TX' => 'Texas',
49
+ 'UT' => 'Utah',
50
+ 'VT' => 'Vermont',
51
+ 'VA' => 'Virginia',
52
+ 'WA' => 'Washington',
53
+ 'WV' => 'West Virginia',
54
+ 'WI' => 'Wisconsin',
55
+ 'WY' => 'Wyoming'
56
+ }
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,143 @@
1
+ module IfdTools
2
+ module Tracking
3
+ module CustomerTracking
4
+
5
+ def self.included(dsl)
6
+
7
+ # Action item to view trends of the resource
8
+ dsl.action_item only: [:show, :edit] do
9
+ link_to "Trends", [:trends, :admin, resource]
10
+ end
11
+
12
+ # Actual controller action for viewing the trends
13
+ dsl.send(:member_action, :trends) do
14
+ @customer = Customer.find_by_url! params[:id]
15
+ @trends = IfdTools::Tracking::Event.where(customer_id: @customer.id).limit(75)
16
+ @registration_date = @customer.created_at
17
+ @application_launches = IfdTools::Tracking::ApplicationEvent.where(customer_id: @customer.id).count
18
+ end
19
+
20
+ # Sidebar when viewing trends for resource
21
+ dsl.sidebar :trend_info, only: :trends
22
+
23
+ # Provides XML for the USA map
24
+ dsl.send(:collection_action, :demographic_data) do
25
+
26
+ @total_activity = IfdTools::Tracking::Event.count
27
+ @activity = []
28
+
29
+ db_activity_per_state = IfdTools::Tracking::Event.includes(:customer).group("customers.state").count
30
+ users_per_state = Customer.group(:state).count
31
+
32
+ IfdTools::States::all.each do |state, long_name|
33
+ @activity << OpenStruct.new(name: long_name, activity: db_activity_per_state[state] || 0.00, users: users_per_state[state] || 0)
34
+ end
35
+
36
+ end
37
+
38
+ dsl.send(:collection_action, :filter_events, method: :post) do
39
+
40
+ cookies[:filter_events] = params[:q].to_yaml
41
+ respond_to do |format|
42
+ format.js
43
+ format.html { redirect_to admin_dashboard_url }
44
+ end
45
+
46
+ end
47
+
48
+ # Provides XML for FusionCharts content graph on dashboard
49
+ dsl.send(:collection_action, :events_data) do
50
+
51
+ filters = YAML.load(cookies[:filter_events]).symbolize_keys rescue {}
52
+ @color = IfdTools::Configure.dashboard_graph_color
53
+ @events = IfdTools::Tracking::Event.scoped
54
+
55
+ unless filters.empty?
56
+
57
+ @events = IfdTools::Tracking::Event.search(filters)
58
+ if filters[:timestamp_gte].present? and filters[:timestamp_lte].present?
59
+ @time_range = "Between #{filters[:timestamp_gte]} and #{filters[:timestamp_lte]}"
60
+ elsif filters[:timestamp_gte].present?
61
+ @time_range = "Since #{filters[:timestamp_gte]}"
62
+ elsif filters[:timestamp_lte].present?
63
+ @time_range = "Before #{filters[:timestamp_lte]}"
64
+ end
65
+
66
+ @filter_type = filters[:type_eq].gsub("IfdTools::Tracking::", "").titleize rescue nil
67
+ @filter_type = "Everything" if @filter_type.blank?
68
+
69
+ @caption = "Activity #{@time_range || 'for All Time'}"
70
+ @subcaption = "Type: #{@filter_type}"
71
+
72
+ @subcaption << " (Mac)" if filters[:platform_eq] == "mac"
73
+ @subcaption << " (PC)" if filters[:platform_eq] == "pc"
74
+
75
+ end
76
+
77
+ # Grab the date/value pairs from the db
78
+ @events = @events.group("date(timestamp)")
79
+
80
+ # Depending on how many records exist, want to narrow that down a good bit
81
+ distribution = @events.count
82
+ first_date = distribution.keys.first.to_date
83
+ last_date = distribution.keys.last.to_date
84
+ num_days_in_time_span = (first_date..last_date).count rescue 0
85
+
86
+ grouping = :days
87
+ if num_days_in_time_span > 450 # ~ 15 months
88
+ @events = @events.group_by { |e| e.timestamp.beginning_of_year.to_date }
89
+ grouping = :years
90
+ elsif num_days_in_time_span > 175 # 7 weeks
91
+ @events = @events.group_by { |e| e.timestamp.beginning_of_month.to_date }
92
+ grouping = :months
93
+ elsif num_days_in_time_span > 25 # 25 days
94
+ @events = @events.group_by { |e| e.timestamp.beginning_of_week.to_date }
95
+ grouping = :weeks
96
+ else
97
+ @events = @events.count
98
+ end
99
+
100
+ # End up with Hash of date => count pairs
101
+ unless grouping == :days
102
+ @events.delete_if { |k, v| v.nil? }.map { |date, arr| @events[date] = arr.count }
103
+ end
104
+
105
+ # Start/end dates might have changed
106
+ first_date = @events.keys.first.to_date
107
+ last_date = @events.keys.last.to_date
108
+
109
+ date_step =
110
+ case grouping
111
+ when :years
112
+ 1.year
113
+ when :months
114
+ 1.month
115
+ when :weeks
116
+ 1.week
117
+ else
118
+ 1.day
119
+ end
120
+
121
+ # Was using a gorgeous "first_date.step(last_date, 1.month).to_a" syntax, but that didn't work in Ruby 1.9.3 for some reason
122
+ event_keys = []
123
+ unless first_date.nil?
124
+ curr_date = first_date.dup
125
+ until curr_date > last_date do
126
+ event_keys << curr_date.to_s
127
+ curr_date += date_step
128
+ end
129
+ end
130
+
131
+ # End up with just { date => FixNum } pairs, with zero values for dates that weren't in the db
132
+ @events = event_keys.inject({}) { |k, v| k[v] = 0; k }.merge(@events)
133
+
134
+ # Only wanted to use this for one request only
135
+ cookies.delete(:filter_events)
136
+
137
+ end
138
+
139
+ end
140
+
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,28 @@
1
+ module IfdTools
2
+ module Trackable
3
+
4
+ def self.included(base)
5
+ base.class_eval do
6
+ has_many :tracking_events, :class_name => 'IfdTools::Tracking::Event', foreign_key: :trackable_id, dependent: :destroy
7
+ end
8
+ end
9
+
10
+ def trackable_title
11
+ name rescue title
12
+ end
13
+
14
+ def trackable_type
15
+ self.class.name.titleize
16
+ end
17
+
18
+ # Override if you might want to link to something else
19
+ def trackable_resource
20
+ self
21
+ end
22
+
23
+ def trackable_activity
24
+ tracking_events.count
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,17 @@
1
+ module IfdTools
2
+ module Validations
3
+
4
+ module Phone
5
+ def validates_phone(*args)
6
+ options = { :format => { :with => /^\(?\d{3}\)?\s*[-|.]?\s*\d{3}\s*[-|.]?\d{4}\s*$/, :message => "'%{value}' is not a valid phone number" } }
7
+ if !args.empty? and args.last.is_a?(Hash)
8
+ options.merge! args.pop
9
+ end
10
+ args.each { |attribute| validates attribute.to_sym, options }
11
+ end
12
+ end
13
+
14
+ end
15
+ end
16
+
17
+ ActiveRecord::Base.send(:extend, IfdTools::Validations::Phone)
@@ -0,0 +1,3 @@
1
+ module IfdTools
2
+ VERSION = "0.1.0"
3
+ end
data/lib/ifd_tools.rb ADDED
@@ -0,0 +1,26 @@
1
+ require 'carrierwave'
2
+ require 'cancan'
3
+ require 'active_admin'
4
+ require 'delayed_job_active_record'
5
+ require 'devise-async'
6
+ require 'cocoon'
7
+ require 'compass-rails'
8
+ require 'ckeditor-rails'
9
+ require 'stringex'
10
+ require 'daemons'
11
+ require 'haml'
12
+ require 'swfobject-rails'
13
+
14
+ require "ifd_tools/engine"
15
+ require 'ifd_tools/date_time_additions'
16
+ require 'ifd_tools/active_admin/base'
17
+ require 'ifd_tools/validations/phone'
18
+
19
+ module IfdTools
20
+
21
+ autoload :ApiControllerExtensions, 'ifd_tools/api_controller_extensions'
22
+ autoload :Configure, 'ifd_tools/configure'
23
+ autoload :States, 'ifd_tools/states'
24
+ autoload :Trackable, 'ifd_tools/tracking/trackable'
25
+
26
+ end
@@ -0,0 +1,2 @@
1
+ namespace :ifd_tools do
2
+ end