sir_tracks_alot 0.4.0 → 0.6.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. data/Gemfile +2 -1
  2. data/Gemfile.lock +54 -0
  3. data/README.rdoc +29 -1
  4. data/VERSION +1 -1
  5. data/benchmarks/activity_benchmark.rb +22 -23
  6. data/benchmarks/benchmark_helper.rb +30 -0
  7. data/benchmarks/count_benchmark.rb +33 -0
  8. data/lib/sir_tracks_alot.rb +16 -14
  9. data/lib/sir_tracks_alot/activity.rb +7 -6
  10. data/lib/sir_tracks_alot/clock.rb +4 -0
  11. data/lib/sir_tracks_alot/count.rb +87 -39
  12. data/lib/sir_tracks_alot/event_helper.rb +1 -1
  13. data/lib/sir_tracks_alot/filter_helper.rb +28 -18
  14. data/lib/sir_tracks_alot/persistable.rb +4 -0
  15. data/lib/sir_tracks_alot/queue/report_cache.rb +2 -0
  16. data/lib/sir_tracks_alot/queue/report_config.rb +3 -0
  17. data/lib/sir_tracks_alot/queue/report_queue.rb +8 -10
  18. data/lib/sir_tracks_alot/reports/actor_activity_report.rb +3 -3
  19. data/lib/sir_tracks_alot/reports/basic_report.rb +1 -1
  20. data/lib/sir_tracks_alot/reports/filter_report.rb +5 -11
  21. data/lib/sir_tracks_alot/reports/report.rb +16 -2
  22. data/lib/sir_tracks_alot/reports/simple_report.rb +43 -0
  23. data/lib/sir_tracks_alot/reports/target_report.rb +2 -7
  24. data/lib/sir_tracks_alot/summary.rb +9 -0
  25. data/sir_tracks_alot.gemspec +140 -0
  26. data/spec/activity_spec.rb +18 -59
  27. data/spec/count_spec.rb +56 -25
  28. data/spec/queue/report_queue_spec.rb +8 -8
  29. data/spec/redis_spec_helper.rb +8 -0
  30. data/spec/reports/actor_report_spec.rb +16 -16
  31. data/spec/reports/filter_report_spec.rb +1 -1
  32. data/spec/reports/report_spec.rb +15 -0
  33. data/spec/reports/root_stem_report_spec.rb +1 -1
  34. data/spec/reports/simple_report_spec.rb +63 -0
  35. data/spec/reports/target_report_spec.rb +9 -4
  36. data/spec/sir_tracks_alot_spec.rb +4 -0
  37. data/spec/spec_helper.rb +1 -9
  38. metadata +38 -10
@@ -1,6 +1,6 @@
1
1
  module SirTracksAlot
2
2
  module EventHelper
3
- DATE_FORMATS = {:hourly => '%Y/%m/%d %H', :daily => '%Y/%m/%d'}
3
+ DATE_FORMATS = {:hourly => '%Y/%m/%d %H:00', :daily => '%Y/%m/%d'}
4
4
 
5
5
  def views(resolution = nil)
6
6
  return events.size if resolution.nil?
@@ -5,33 +5,43 @@ module SirTracksAlot
5
5
  # Regular Expression filters match against retrieved attribute values
6
6
  #
7
7
  # filter(:actor => 'user1', :target => /\/targets\/\d+/, :action => ['view', 'create'], :category => ['/root', '/other_root'])
8
- def filter(options_for_find, &block)
8
+ def filter(filters, &block)
9
9
  items = []
10
10
  all = []
11
11
 
12
- strings, matchers, arrays = extract_filter_options(options_for_find)
12
+ filters = [filters] unless filters.kind_of?(Array)
13
13
 
14
- unless arrays.empty?
15
- (arrays.values.inject{|a, b| a.product b}).each do |combo|
16
- terms = {}; combo.each{|c| terms[find_key_from_value(arrays, c)] = c}
17
- all += find(terms.merge(strings)).to_a
18
- end
19
- else
20
- all = find(strings)
21
- end
14
+ filters.each do |options_for_find|
15
+ strings, matchers, arrays = extract_filter_options(options_for_find)
22
16
 
23
- all.each do |item|
24
- pass = true
25
-
26
- matchers.each do |key, matcher|
27
- pass = false if !matcher.match(item.send(key))
17
+ unless arrays.empty?
18
+ (arrays.values.inject{|a, b| a.product b}).each do |combo|
19
+ combo = [combo] unless combo.kind_of?(Array)
20
+ terms = {}; combo.each{|c| terms[find_key_from_value(arrays, c)] = c}
21
+ if terms.values.detect{|t| t.kind_of?(Regexp)}
22
+ matchers.merge!(terms)
23
+ next
24
+ end
25
+
26
+ all += find(terms.merge(strings)).to_a
27
+ end
28
+ else
29
+ all += find(strings).to_a
28
30
  end
29
31
 
30
- next unless pass
32
+ all.each do |item|
33
+ pass = true
34
+
35
+ matchers.each do |key, matcher|
36
+ pass = false if !matcher.match(item.send(key))
37
+ end
38
+
39
+ next unless pass
31
40
 
32
- yield item if block_given?
41
+ # yield item if block_given?
33
42
 
34
- items << item
43
+ items << item
44
+ end
35
45
  end
36
46
 
37
47
  items
@@ -24,6 +24,10 @@ module SirTracksAlot
24
24
  self.id == comparee.id
25
25
  end
26
26
 
27
+ def to_hash
28
+ super
29
+ end
30
+
27
31
 
28
32
  protected
29
33
 
@@ -4,8 +4,10 @@ module SirTracksAlot
4
4
  attribute :created_at
5
5
  attribute :report
6
6
  attribute :owner
7
+ attribute :name
7
8
  attribute :html
8
9
 
10
+ index :name
9
11
  index :report
10
12
  index :owner
11
13
  end
@@ -6,9 +6,11 @@ module SirTracksAlot
6
6
 
7
7
  attribute :created_at
8
8
  attribute :report
9
+ attribute :name
9
10
  attribute :owner
10
11
  attribute :options_store
11
12
 
13
+ index :name
12
14
  index :report
13
15
  index :owner
14
16
 
@@ -24,6 +26,7 @@ module SirTracksAlot
24
26
  def validate
25
27
  assert_present :report
26
28
  assert_present :owner
29
+ assert_present :name
27
30
  end
28
31
  end
29
32
  end
@@ -8,9 +8,9 @@ module SirTracksAlot
8
8
  index :name
9
9
  list :queue # of ReportConfigs
10
10
 
11
- def self.push(owner, report, options)
12
- config = ReportConfig.find_or_create(:owner => owner.to_s, :report => report.to_s)
13
- config.options = options.merge(:owner => owner.to_s) # reports require owner, should be sync'd with config owner
11
+ def self.push(owner, report, name, options)
12
+ config = ReportConfig.find_or_create(:owner => owner.to_s, :report => report.to_s, :name => name.to_s)
13
+ config.options = options
14
14
  queue = self.find_or_create(:name => QUEUE_NAME)
15
15
  queue.queue << config.id
16
16
  end
@@ -23,13 +23,12 @@ module SirTracksAlot
23
23
  return false
24
24
  end
25
25
 
26
- queue = queue.first
26
+ queue = queue.first
27
+ config = ReportConfig[queue.queue.pop] # raw gets us just the id's, pop to remove the las one, it's a queue!
27
28
 
28
- config = ReportConfig[queue.queue.pop] # raw gets us just the id's, pop to remove the las one, it's a queue!
29
-
30
29
  process(config)
31
30
  end
32
-
31
+
33
32
  def self.process(config)
34
33
  return false if config.nil?
35
34
 
@@ -37,9 +36,8 @@ module SirTracksAlot
37
36
 
38
37
  begin
39
38
  report = QueueHelper.constantize(QueueHelper.camelize("SirTracksAlot::Reports::#{config.report.capitalize}"))
40
- counts = Count.filter(config.options)
41
- html = report.render_html(:counts => counts)
42
- cache = ReportCache.find_or_create(:owner => config.owner, :report => config.report)
39
+ html = report.render_html(config.options)
40
+ cache = ReportCache.find_or_create(:owner => config.owner, :report => config.report, :name => config.name)
43
41
  cache.update(:html => html)
44
42
  rescue Exception => e
45
43
  SirTracksAlot.log.fatal("Error building report #{config.report} for #{config.owner}: #{e}")
@@ -24,12 +24,12 @@ module SirTracksAlot
24
24
  t << [target, count[0], count[1]]
25
25
  end
26
26
  end
27
-
27
+
28
28
  table.sort_rows_by!('page views', :order => :descending)
29
-
29
+
30
30
  self.data = table
31
31
  end
32
-
32
+
33
33
  module Helpers
34
34
  include Report::Helpers
35
35
  end
@@ -13,7 +13,7 @@ module SirTracksAlot
13
13
 
14
14
  self.data = grouping
15
15
  end
16
-
16
+
17
17
  module Helpers
18
18
  include Report::Helpers
19
19
  end
@@ -8,17 +8,10 @@ module SirTracksAlot
8
8
 
9
9
  # Build up reports by filtering things. Filters are applied and assigned a row title.
10
10
  #
11
- # SirTracksAlot::Reports::FilterReport.render_html(
12
- # :actions => ['view', 'search']
13
- #
14
11
  # :filters = {
15
12
  # 'Title' => {:category => 'category', :target => /\/categories/}
16
13
  # }
17
14
  #
18
- # :filters => {
19
- # :only => {Profile Pages' => {:target => /^\/user_profiles\/.+$/}}
20
- # :except => {Profile Index' => {:target => /^\/user_profiles$/}}
21
- # })
22
15
  def setup
23
16
  super
24
17
 
@@ -26,12 +19,13 @@ module SirTracksAlot
26
19
  options.filters ||= {}
27
20
  options.column_names ||= COLUMN_NAMES
28
21
 
29
-
30
22
  options.filters.each do |title, options_for_find|
31
23
  Count.filter(options_for_find.merge(:owner => options.owner)).each do |count|
32
- counts[title] ||= [0,0]
33
- counts[title][0] += count.visits.to_i
34
- counts[title][1] += count.views.to_i
24
+ count.summaries.each do |summary|
25
+ counts[title] ||= [0,0]
26
+ counts[title][0] += summary.visits.to_i
27
+ counts[title][1] += summary.views.to_i
28
+ end
35
29
  end
36
30
  end
37
31
 
@@ -3,12 +3,26 @@ module SirTracksAlot
3
3
  class Report < Ruport::Controller
4
4
  attr_accessor :all
5
5
 
6
+ # Accepts either:
7
+ # options: {'title' => {:owner => 'xxx'}}
8
+ # options: [{:owner => 'xxx'}]
9
+ def self.build_rows(filters)
10
+ rows = []
11
+ filters = {nil => filters} if filters.kind_of?(Array)
12
+
13
+ filters.each do |title, options_for_find|
14
+ rows += SirTracksAlot::Count.rows(options_for_find, title)
15
+ end
16
+
17
+ rows
18
+ end
19
+
6
20
  def setup
7
21
  self.data = []
8
22
  options.report_class ||= ''
9
23
  options.report_title ||= 'Report'
10
- end
11
-
24
+ end
25
+
12
26
  module Helpers
13
27
  def self.handle(name, &block)
14
28
  @@handlers ||= {}
@@ -0,0 +1,43 @@
1
+ module SirTracksAlot
2
+ module Reports
3
+ class SimpleReport < Report
4
+ COLUMN_NAMES = ['target', 'page views', 'visits']
5
+
6
+ stage :simple
7
+
8
+ def setup
9
+ options.column_names ||= COLUMN_NAMES
10
+
11
+ rows = Report.build_rows(options.filters)
12
+
13
+ table = Table(options.column_names, :data => rows)
14
+
15
+ if options.group
16
+ grouping = Grouping(table, :by => options.group, :order => options.group)
17
+ grouping.each{|n, g| g.sort_rows_by!('count', :order => :descending)}
18
+ self.data = grouping
19
+ else
20
+ table.sort_rows_by!('page views', :order => :descending)
21
+ self.data = table
22
+ end
23
+
24
+ end
25
+
26
+ module Helpers
27
+ include Report::Helpers
28
+ end
29
+
30
+ class HTML < Ruport::Formatter::HTML
31
+ renders :html, :for => SimpleReport
32
+
33
+ build :simple do
34
+ if options.group
35
+ output << erb((options.template || TRACKABLE_ROOT+"/views/reports/group.html.erb"), :binding => binding)
36
+ else
37
+ output << erb((options.template || TRACKABLE_ROOT+"/views/reports/table.html.erb"), :binding => binding)
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -8,14 +8,9 @@ module SirTracksAlot
8
8
  def setup
9
9
  super
10
10
  column_names = options.column_names || COLUMN_NAMES
11
- counts = options.counts || {}
12
-
13
- table = Table(column_names) do |t|
14
- counts.each do |count|
15
- t << [count.target, count.visits, count.views]
16
- end
17
- end
11
+ rows = options.rows || []
18
12
 
13
+ table = Table(column_names, :data => rows)
19
14
  table.sort_rows_by!('page views', :order => :descending)
20
15
 
21
16
  self.data = table
@@ -0,0 +1,9 @@
1
+ module SirTracksAlot
2
+ class Summary < Persistable
3
+ attribute :date # 234234234
4
+ attribute :views
5
+ attribute :visits
6
+
7
+ index :date
8
+ end
9
+ end
@@ -0,0 +1,140 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{sir_tracks_alot}
8
+ s.version = "0.6.2"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Peter T. Brown"]
12
+ s.date = %q{2010-10-18}
13
+ s.description = %q{A high speed general purpose tracking and reporting tool which uses Redis.}
14
+ s.email = %q{peter@flippyhead.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ "Gemfile",
21
+ "Gemfile.lock",
22
+ "LICENSE",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "benchmarks/activity_benchmark.rb",
27
+ "benchmarks/benchmark_helper.rb",
28
+ "benchmarks/count_benchmark.rb",
29
+ "benchmarks/report_benchmark.rb",
30
+ "lib/sir_tracks_alot.rb",
31
+ "lib/sir_tracks_alot/activity.rb",
32
+ "lib/sir_tracks_alot/clock.rb",
33
+ "lib/sir_tracks_alot/count.rb",
34
+ "lib/sir_tracks_alot/event_helper.rb",
35
+ "lib/sir_tracks_alot/filter_helper.rb",
36
+ "lib/sir_tracks_alot/persistable.rb",
37
+ "lib/sir_tracks_alot/queue/queue_helper.rb",
38
+ "lib/sir_tracks_alot/queue/report_cache.rb",
39
+ "lib/sir_tracks_alot/queue/report_config.rb",
40
+ "lib/sir_tracks_alot/queue/report_queue.rb",
41
+ "lib/sir_tracks_alot/reports/activity_report.rb",
42
+ "lib/sir_tracks_alot/reports/actor_activity_report.rb",
43
+ "lib/sir_tracks_alot/reports/actor_report.rb",
44
+ "lib/sir_tracks_alot/reports/basic_report.rb",
45
+ "lib/sir_tracks_alot/reports/filter_report.rb",
46
+ "lib/sir_tracks_alot/reports/report.rb",
47
+ "lib/sir_tracks_alot/reports/root_stem_report.rb",
48
+ "lib/sir_tracks_alot/reports/simple_report.rb",
49
+ "lib/sir_tracks_alot/reports/target_report.rb",
50
+ "lib/sir_tracks_alot/reports/trackable_report.rb",
51
+ "lib/sir_tracks_alot/summary.rb",
52
+ "sir_tracks_alot.gemspec",
53
+ "spec/activity_spec.rb",
54
+ "spec/count_spec.rb",
55
+ "spec/queue/report_config_spec.rb",
56
+ "spec/queue/report_queue_spec.rb",
57
+ "spec/redis_spec_helper.rb",
58
+ "spec/reports/activity_report_spec.rb",
59
+ "spec/reports/actor_activity_report_spec.rb",
60
+ "spec/reports/actor_report_spec.rb",
61
+ "spec/reports/basic_report_spec.rb",
62
+ "spec/reports/filter_report_spec.rb",
63
+ "spec/reports/report_spec.rb",
64
+ "spec/reports/root_stem_report_spec.rb",
65
+ "spec/reports/shared_report_specs.rb",
66
+ "spec/reports/simple_report_spec.rb",
67
+ "spec/reports/target_report_spec.rb",
68
+ "spec/sir_tracks_alot_spec.rb",
69
+ "spec/spec.opts",
70
+ "spec/spec_helper.rb",
71
+ "test/helper.rb",
72
+ "test/test_sir_tracks_alot.rb",
73
+ "views/reports/group.html.erb",
74
+ "views/reports/table.html.erb"
75
+ ]
76
+ s.homepage = %q{http://github.com/flippyhead/sir_tracks_alot}
77
+ s.rdoc_options = ["--charset=UTF-8"]
78
+ s.require_paths = ["lib"]
79
+ s.rubygems_version = %q{1.3.7}
80
+ s.summary = %q{A high speed general purpose tracking and reporting tool which uses Redis.}
81
+ s.test_files = [
82
+ "spec/activity_spec.rb",
83
+ "spec/count_spec.rb",
84
+ "spec/queue/report_config_spec.rb",
85
+ "spec/queue/report_queue_spec.rb",
86
+ "spec/redis_spec_helper.rb",
87
+ "spec/reports/activity_report_spec.rb",
88
+ "spec/reports/actor_activity_report_spec.rb",
89
+ "spec/reports/actor_report_spec.rb",
90
+ "spec/reports/basic_report_spec.rb",
91
+ "spec/reports/filter_report_spec.rb",
92
+ "spec/reports/report_spec.rb",
93
+ "spec/reports/root_stem_report_spec.rb",
94
+ "spec/reports/shared_report_specs.rb",
95
+ "spec/reports/simple_report_spec.rb",
96
+ "spec/reports/target_report_spec.rb",
97
+ "spec/sir_tracks_alot_spec.rb",
98
+ "spec/spec_helper.rb",
99
+ "test/helper.rb",
100
+ "test/test_sir_tracks_alot.rb"
101
+ ]
102
+
103
+ if s.respond_to? :specification_version then
104
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
105
+ s.specification_version = 3
106
+
107
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
108
+ s.add_runtime_dependency(%q<logging>, [">= 0"])
109
+ s.add_runtime_dependency(%q<twitter>, [">= 0"])
110
+ s.add_runtime_dependency(%q<ruport>, [">= 0"])
111
+ s.add_runtime_dependency(%q<ohm>, ["= 0.0.38"])
112
+ s.add_runtime_dependency(%q<redis>, [">= 0"])
113
+ s.add_development_dependency(%q<rspec>, [">= 0"])
114
+ s.add_development_dependency(%q<color>, [">= 0"])
115
+ s.add_development_dependency(%q<rspec_hpricot_matchers>, [">= 0"])
116
+ s.add_development_dependency(%q<hpricot>, [">= 0"])
117
+ else
118
+ s.add_dependency(%q<logging>, [">= 0"])
119
+ s.add_dependency(%q<twitter>, [">= 0"])
120
+ s.add_dependency(%q<ruport>, [">= 0"])
121
+ s.add_dependency(%q<ohm>, ["= 0.0.38"])
122
+ s.add_dependency(%q<redis>, [">= 0"])
123
+ s.add_dependency(%q<rspec>, [">= 0"])
124
+ s.add_dependency(%q<color>, [">= 0"])
125
+ s.add_dependency(%q<rspec_hpricot_matchers>, [">= 0"])
126
+ s.add_dependency(%q<hpricot>, [">= 0"])
127
+ end
128
+ else
129
+ s.add_dependency(%q<logging>, [">= 0"])
130
+ s.add_dependency(%q<twitter>, [">= 0"])
131
+ s.add_dependency(%q<ruport>, [">= 0"])
132
+ s.add_dependency(%q<ohm>, ["= 0.0.38"])
133
+ s.add_dependency(%q<redis>, [">= 0"])
134
+ s.add_dependency(%q<rspec>, [">= 0"])
135
+ s.add_dependency(%q<color>, [">= 0"])
136
+ s.add_dependency(%q<rspec_hpricot_matchers>, [">= 0"])
137
+ s.add_dependency(%q<hpricot>, [">= 0"])
138
+ end
139
+ end
140
+