widescreen 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore ADDED
@@ -0,0 +1,20 @@
1
+ # rcov generated
2
+ coverage
3
+
4
+ # rdoc generated
5
+ rdoc
6
+
7
+ # yard generated
8
+ doc
9
+ .yardoc
10
+
11
+ # bundler
12
+ .bundle
13
+
14
+ # jeweler generated
15
+ pkg
16
+
17
+ .DS_Store
18
+
19
+ Gemfile.lock
20
+ .rvmrc
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ rvm:
2
+ - 1.8.7
3
+ - 1.9.2
4
+ - 1.9.3
5
+ - rbx
6
+ - jruby
7
+ - ree
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Marcin Ciunelis
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,122 @@
1
+ # Widescreen[![travis-ci](https://secure.travis-ci.org/martinciu/widescreen.png?branch=master)](http://travis-ci.org/martinciu/widescreen)
2
+ Rack based event statistic framework for any Rack app
3
+
4
+ ## Requirements
5
+
6
+ Widescreen uses redis as a datastore.
7
+
8
+ Widescreen only supports redis 2.0 or greater.
9
+
10
+ If you're on OS X, Homebrew is the simplest way to install Redis:
11
+
12
+ $ brew install redis
13
+ $ redis-server /usr/local/etc/redis.conf
14
+
15
+ You now have a Redis daemon running on 6379.
16
+
17
+ ## Setup
18
+
19
+ If you are using bundler add widescreen to your Gemfile:
20
+
21
+ gem 'widescreen'
22
+
23
+ Then run:
24
+
25
+ bundle install
26
+
27
+ Otherwise install the gem:
28
+
29
+ gem install widescreen
30
+
31
+ and require it in your project:
32
+
33
+ require 'widescreen'
34
+
35
+ ## Usage
36
+
37
+ Anywhere in you code call
38
+
39
+ Widescreen::Stat.add(:metric_name, 10)
40
+
41
+ to increase counter by 10 for `metric_name` metric or
42
+
43
+ Widescreen::Stat.add(:metric_name)
44
+
45
+ to increase it by 1
46
+
47
+ ## Web Interface
48
+
49
+ Web interface is on to-do list. It will be simple sinatra app similar to Resque web interface
50
+
51
+ ## Configuration
52
+
53
+ ### Redis
54
+
55
+ You may want to change the Redis host and port Wide connects to, or
56
+ set various other options at startup.
57
+
58
+ Widescreen has a `redis` setter which can be given a string or a Redis
59
+ object. This means if you're already using Redis in your app, Widescreen
60
+ can re-use the existing connection.
61
+
62
+ String: `Widescreen.redis = 'localhost:6379'`
63
+
64
+ Redis: `Widescreen.redis = $redis`
65
+
66
+ For our rails app we have a `config/initializers/widescreen.rb` file where
67
+ we load `config/widescreen.yml` by hand and set the Redis information
68
+ appropriately.
69
+
70
+ Here's our `config/widescreen.yml`:
71
+
72
+ development: localhost:6379
73
+ test: localhost:6379
74
+ staging: redis1.example.com:6379
75
+ fi: localhost:6379
76
+ production: redis1.example.com:6379
77
+
78
+ And our initializer:
79
+
80
+ rails_root = ENV['RAILS_ROOT'] || File.dirname(__FILE__) + '/../..'
81
+ rails_env = ENV['RAILS_ENV'] || 'development'
82
+
83
+ widescreen_config = YAML.load_file(rails_root + '/config/widescreen.yml')
84
+ Widescreen.redis = widescreen_config[rails_env]
85
+
86
+ ## Namespaces
87
+
88
+ If you're running multiple, separate instances of widescreen you may want
89
+ to namespace the keyspaces so they do not overlap. This is not unlike
90
+ the approach taken by many memcached clients.
91
+
92
+ This feature is provided by the [redis-namespace][rs] library, which
93
+ widescreen uses by default to separate the keys it manages from other keys
94
+ in your Redis server.
95
+
96
+ Simply use the `Widescreen.redis.namespace` accessor:
97
+
98
+ Widescreen.redis.namespace = "widescreen:blog"
99
+
100
+ We recommend sticking this in your initializer somewhere after Redis
101
+ is configured.
102
+
103
+ ## Development
104
+
105
+ Source hosted at [GitHub](http://github.com/martinciu/widescreen).
106
+ Report Issues/Feature requests on [GitHub Issues](http://github.com/martinciu/widescreen/issues).
107
+
108
+ Tests can be ran with `rake test`
109
+
110
+ ### Note on Patches/Pull Requests
111
+
112
+ * Fork the project.
113
+ * Make your feature addition or bug fix.
114
+ * Add tests for it. This is important so I don't break it in a
115
+ future version unintentionally.
116
+ * Commit, do not mess with rakefile, version, or history.
117
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
118
+ * Send me a pull request. Bonus points for topic branches.
119
+
120
+ ## Copyright
121
+
122
+ Copyright (c) 2011 Marcin Ciunelis. See [LICENSE](https://github.com/martinciu/widescreen/blob/master/LICENSE) for details.
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require 'rake/testtask'
2
+ require 'bundler/gem_tasks'
3
+ Bundler.setup(:default, :test)
4
+
5
+ Rake::TestTask.new do |t|
6
+ t.libs << "spec"
7
+ t.test_files = FileList['spec/**/*_spec.rb']
8
+ t.verbose = true
9
+ end
10
+
11
+ task :default => :test
@@ -0,0 +1,58 @@
1
+ module Widescreen
2
+ class Metric
3
+ attr_accessor :name
4
+
5
+ def initialize(name)
6
+ @name = name
7
+ end
8
+
9
+ def new_record?
10
+ !Widescreen.redis.sismember(:metrics, name)
11
+ end
12
+
13
+ def save
14
+ return false unless valid?
15
+ Widescreen.redis.sadd(:metrics, name) if new_record?
16
+ true
17
+ end
18
+
19
+ def valid?
20
+ !name.empty?
21
+ end
22
+
23
+ def push(value)
24
+ Widescreen::Stat.add(self, value)
25
+ end
26
+
27
+ def stats
28
+ Widescreen.redis.keys("#{name}#{Widescreen::SEPARATOR}*").map { |s| Widescreen::Stat.find(s) }
29
+ end
30
+
31
+ def self.find(name)
32
+ new(name)
33
+ end
34
+
35
+ def to_s
36
+ name
37
+ end
38
+
39
+ def self.find_or_create(metric)
40
+ if Widescreen.redis.sismember(:metrics, metric)
41
+ find(metric)
42
+ else
43
+ create(metric)
44
+ end
45
+ end
46
+
47
+ def self.all
48
+ Widescreen.redis.smembers(:metrics).map {|m| find(m)}
49
+ end
50
+
51
+ def self.create(name)
52
+ metric = new(name)
53
+ metric.save
54
+ metric
55
+ end
56
+
57
+ end
58
+ end
@@ -0,0 +1,38 @@
1
+ module Widescreen
2
+ class Stat
3
+ attr_accessor :metric, :time, :value
4
+
5
+ def initialize(metric, time, value = 1)
6
+ @metric = Widescreen::Metric.find_or_create(metric)
7
+ @time = time
8
+ @value = value
9
+ end
10
+
11
+ def save
12
+ Widescreen.redis.incrby(key, value)
13
+ end
14
+
15
+ def self.add(metric, value = 1)
16
+ new(metric, Time.now, value).save
17
+ end
18
+
19
+ def self.find(key)
20
+ value = Widescreen.redis.get(key)
21
+ return if value.nil?
22
+ metric_name, time = key.split(Widescreen::SEPARATOR, 2)
23
+ new(metric_name, Time.parse(time), value)
24
+ end
25
+
26
+ protected
27
+ def key
28
+ [metric.name, time_string].join(Widescreen::SEPARATOR)
29
+ end
30
+
31
+ def time_string
32
+ time.iso8601
33
+ rescue NoMethodError
34
+ time
35
+ end
36
+
37
+ end
38
+ end
@@ -0,0 +1,3 @@
1
+ module Widescreen
2
+ VERSION = "0.0.1"
3
+ end
data/lib/widescreen.rb ADDED
@@ -0,0 +1,48 @@
1
+ require 'redis/namespace'
2
+ require 'time'
3
+
4
+ require 'widescreen/version'
5
+ require 'widescreen/metric'
6
+ require 'widescreen/stat'
7
+
8
+ module Widescreen
9
+ SEPARATOR = "|"
10
+
11
+ extend self
12
+
13
+ # Accepts:
14
+ # 1. A 'hostname:port' String
15
+ # 2. A 'hostname:port:db' String (to select the Redis db)
16
+ # 3. A 'hostname:port/namespace' String (to set the Redis namespace)
17
+ # 4. A Redis URL String 'redis://host:port'
18
+ # 5. An instance of `Redis`, `Redis::Client`, `Redis::DistRedis`,
19
+ # or `Redis::Namespace`.
20
+ def redis=(server)
21
+ case server
22
+ when String
23
+ if server =~ /redis\:\/\//
24
+ redis = Redis.connect(:url => server, :thread_safe => true)
25
+ else
26
+ server, namespace = server.split('/', 2)
27
+ host, port, db = server.split(':')
28
+ redis = Redis.new(:host => host, :port => port,
29
+ :thread_safe => true, :db => db)
30
+ end
31
+ namespace ||= :resque
32
+
33
+ @redis = Redis::Namespace.new(namespace, :redis => redis)
34
+ when Redis::Namespace
35
+ @redis = server
36
+ else
37
+ @redis = Redis::Namespace.new(:resque, :redis => server)
38
+ end
39
+ end
40
+
41
+ # Returns the current Redis connection. If none has been created, will
42
+ # create a new one.
43
+ def redis
44
+ return @redis if @redis
45
+ self.redis = Redis.respond_to?(:connect) ? Redis.connect : "localhost:6379"
46
+ self.redis
47
+ end
48
+ end
@@ -0,0 +1,115 @@
1
+ # Redis configuration file example
2
+
3
+ # By default Redis does not run as a daemon. Use 'yes' if you need it.
4
+ # Note that Redis will write a pid file in /var/run/redis.pid when daemonized.
5
+ daemonize yes
6
+
7
+ # When run as a daemon, Redis write a pid file in /var/run/redis.pid by default.
8
+ # You can specify a custom pid file location here.
9
+ pidfile ./spec/redis-test.pid
10
+
11
+ # Accept connections on the specified port, default is 6379
12
+ port 9736
13
+
14
+ # If you want you can bind a single interface, if the bind option is not
15
+ # specified all the interfaces will listen for connections.
16
+ #
17
+ # bind 127.0.0.1
18
+
19
+ # Close the connection after a client is idle for N seconds (0 to disable)
20
+ timeout 300
21
+
22
+ # Save the DB on disk:
23
+ #
24
+ # save <seconds> <changes>
25
+ #
26
+ # Will save the DB if both the given number of seconds and the given
27
+ # number of write operations against the DB occurred.
28
+ #
29
+ # In the example below the behaviour will be to save:
30
+ # after 900 sec (15 min) if at least 1 key changed
31
+ # after 300 sec (5 min) if at least 10 keys changed
32
+ # after 60 sec if at least 10000 keys changed
33
+ save 900 1
34
+ save 300 10
35
+ save 60 10000
36
+
37
+ # The filename where to dump the DB
38
+ dbfilename dump.rdb
39
+
40
+ # For default save/load DB in/from the working directory
41
+ # Note that you must specify a directory not a file name.
42
+ dir ./spec/
43
+
44
+ # Set server verbosity to 'debug'
45
+ # it can be one of:
46
+ # debug (a lot of information, useful for development/testing)
47
+ # notice (moderately verbose, what you want in production probably)
48
+ # warning (only very important / critical messages are logged)
49
+ loglevel debug
50
+
51
+ # Specify the log file name. Also 'stdout' can be used to force
52
+ # the demon to log on the standard output. Note that if you use standard
53
+ # output for logging but daemonize, logs will be sent to /dev/null
54
+ logfile stdout
55
+
56
+ # Set the number of databases. The default database is DB 0, you can select
57
+ # a different one on a per-connection basis using SELECT <dbid> where
58
+ # dbid is a number between 0 and 'databases'-1
59
+ databases 16
60
+
61
+ ################################# REPLICATION #################################
62
+
63
+ # Master-Slave replication. Use slaveof to make a Redis instance a copy of
64
+ # another Redis server. Note that the configuration is local to the slave
65
+ # so for example it is possible to configure the slave to save the DB with a
66
+ # different interval, or to listen to another port, and so on.
67
+
68
+ # slaveof <masterip> <masterport>
69
+
70
+ ################################## SECURITY ###################################
71
+
72
+ # Require clients to issue AUTH <PASSWORD> before processing any other
73
+ # commands. This might be useful in environments in which you do not trust
74
+ # others with access to the host running redis-server.
75
+ #
76
+ # This should stay commented out for backward compatibility and because most
77
+ # people do not need auth (e.g. they run their own servers).
78
+
79
+ # requirepass foobared
80
+
81
+ ################################### LIMITS ####################################
82
+
83
+ # Set the max number of connected clients at the same time. By default there
84
+ # is no limit, and it's up to the number of file descriptors the Redis process
85
+ # is able to open. The special value '0' means no limts.
86
+ # Once the limit is reached Redis will close all the new connections sending
87
+ # an error 'max number of clients reached'.
88
+
89
+ # maxclients 128
90
+
91
+ # Don't use more memory than the specified amount of bytes.
92
+ # When the memory limit is reached Redis will try to remove keys with an
93
+ # EXPIRE set. It will try to start freeing keys that are going to expire
94
+ # in little time and preserve keys with a longer time to live.
95
+ # Redis will also try to remove objects from free lists if possible.
96
+ #
97
+ # If all this fails, Redis will start to reply with errors to commands
98
+ # that will use more memory, like SET, LPUSH, and so on, and will continue
99
+ # to reply to most read-only commands like GET.
100
+ #
101
+ # WARNING: maxmemory can be a good idea mainly if you want to use Redis as a
102
+ # 'state' server or cache, not as a real DB. When Redis is used as a real
103
+ # database the memory usage will grow over the weeks, it will be obvious if
104
+ # it is going to use too much memory in the long run, and you'll have the time
105
+ # to upgrade. With maxmemory after the limit is reached you'll start to get
106
+ # errors for write operations, and this may even lead to DB inconsistency.
107
+
108
+ # maxmemory <bytes>
109
+
110
+ ############################### ADVANCED CONFIG ###############################
111
+
112
+ # Glue small output buffers together in order to send small replies in a
113
+ # single TCP packet. Uses a bit more CPU but most of the times it is a win
114
+ # in terms of number of queries per second. Use 'yes' if unsure.
115
+ glueoutputbuf yes
@@ -0,0 +1,47 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ Bundler.setup(:default, :test)
4
+ Bundler.require(:default, :test)
5
+
6
+ dir = File.dirname(File.expand_path(__FILE__))
7
+ $LOAD_PATH.unshift dir + '/../lib'
8
+ $TESTING = true
9
+ require 'minitest/autorun'
10
+ require 'timecop'
11
+
12
+ if !ENV['TRAVIS']
13
+
14
+ # make sure we can run redis
15
+
16
+ if !system("which redis-server")
17
+ puts '', "** can't find `redis-server` in your path"
18
+ puts "** try running `sudo rake install`"
19
+ abort ''
20
+ end
21
+
22
+ #
23
+ # start our own redis when the tests start,
24
+ # kill it when they end
25
+ #
26
+
27
+ at_exit do
28
+ next if $!
29
+
30
+ if defined?(MiniTest)
31
+ exit_code = MiniTest::Unit.new.run(ARGV)
32
+ else
33
+ exit_code = Test::Unit::AutoRunner.run
34
+ end
35
+
36
+ pid = `ps -A -o pid,command | grep [r]edis-test`.split(" ")[0]
37
+ puts "Killing test redis server..."
38
+ `rm -f #{dir}/dump.rdb`
39
+ Process.kill("KILL", pid.to_i)
40
+ exit exit_code
41
+ end
42
+
43
+ puts "Starting redis for testing at localhost:9736..."
44
+ `redis-server #{dir}/redis-test.conf`
45
+ Widescreen.redis = 'localhost:9736'
46
+ end
47
+
@@ -0,0 +1,101 @@
1
+ require 'spec_helper'
2
+
3
+ describe Widescreen::Metric do
4
+
5
+ before(:each) do
6
+ Widescreen.redis.flushall
7
+ end
8
+
9
+ describe "instance methods" do
10
+ describe "initialize" do
11
+ it "set name" do
12
+ Widescreen::Metric.new("foo").name.must_equal "foo"
13
+ end
14
+ end
15
+
16
+ describe "save" do
17
+ it "saves valid record" do
18
+ metric = Widescreen::Metric.new("foo")
19
+ metric.save.must_equal true
20
+ Widescreen.redis.sismember(:metrics, "foo").must_equal true
21
+ end
22
+ it "doesn't save invalid record" do
23
+ metric = Widescreen::Metric.new("")
24
+ metric.save.must_equal false
25
+ Widescreen.redis.sismember(:metrics, "foo").must_equal false
26
+ end
27
+ end
28
+
29
+ describe "valid?" do
30
+ it "returns true if name is not empty" do
31
+ Widescreen::Metric.new("foo").valid?.must_equal true
32
+ end
33
+ it "returns false if name is empty" do
34
+ Widescreen::Metric.new("").valid?.must_equal false
35
+ end
36
+ end
37
+
38
+ describe "new_record?" do
39
+ before {@metric = Widescreen::Metric.new("foo")}
40
+ it { @metric.new_record?.must_equal true }
41
+
42
+ it "knows when it is an existed record" do
43
+ @metric.save
44
+ @metric.new_record?.must_equal false
45
+ end
46
+ end
47
+
48
+ end
49
+
50
+ describe "class methods" do
51
+ describe "create" do
52
+ before { @metric = Widescreen::Metric.create("foo") }
53
+ it { Widescreen.redis.sismember(:metrics, "foo").must_equal true }
54
+ it { @metric.must_be_instance_of Widescreen::Metric }
55
+ end
56
+
57
+ describe "all" do
58
+ before(:each) do
59
+ Widescreen::Metric.create("foo")
60
+ Widescreen::Metric.create("bar")
61
+ Widescreen::Metric.create("baz")
62
+ end
63
+
64
+ it { Widescreen::Metric.all.must_be_instance_of Array }
65
+ it { Widescreen::Metric.all.size.must_equal 3 }
66
+ it "returns array of Metrics" do
67
+ Widescreen::Metric.all.each do |metric|
68
+ metric.must_be_instance_of Widescreen::Metric
69
+ end
70
+ end
71
+ end
72
+
73
+ describe "stats" do
74
+ before(:each) do
75
+ @metric = Widescreen::Metric.create("foo")
76
+ now = Time.now
77
+ [1, 2, 5].each do |n|
78
+ Timecop.freeze(now - n*3600) do
79
+ Widescreen::Stat.add("foo")
80
+ end
81
+ end
82
+ Timecop.freeze(now)
83
+ end
84
+
85
+ after(:each) do
86
+ Timecop.return
87
+ end
88
+
89
+ it { @metric.stats.size.must_equal 3 }
90
+ it { @metric.stats.must_be_instance_of Array}
91
+
92
+ it "returns instances of Stat" do
93
+ @metric.stats.each do |m|
94
+ m.must_be_instance_of Widescreen::Stat
95
+ end
96
+ end
97
+
98
+ end
99
+
100
+ end
101
+ end
@@ -0,0 +1,97 @@
1
+ require 'spec_helper'
2
+
3
+ describe Widescreen::Stat do
4
+ before(:each) do
5
+ Widescreen.redis.flushall
6
+ end
7
+
8
+ describe "instance methods" do
9
+ describe "initialize" do
10
+ before(:each) do
11
+ Timecop.freeze
12
+ @metric = Widescreen::Metric.create("foo")
13
+ @time = Time.now.iso8601
14
+ @stat = Widescreen::Stat.new("foo", @time, 5)
15
+ end
16
+
17
+ after(:each) do
18
+ Timecop.return
19
+ end
20
+
21
+ it "has metric" do
22
+ @stat.metric.must_be_instance_of Widescreen::Metric
23
+ end
24
+
25
+ it "has time" do
26
+ @stat.time.must_equal @time
27
+ end
28
+
29
+ it "has value" do
30
+ @stat.value.must_equal 5
31
+ end
32
+ end
33
+
34
+ describe "find" do
35
+ before(:each) do
36
+ @key = ["foo", Time.now.strftime('%Y-%m-%dT%H')].join(Widescreen::SEPARATOR)
37
+ Widescreen.redis.set(@key, 10)
38
+ end
39
+
40
+ it "returns instance of Stat if it exist" do
41
+ Widescreen::Stat.find(@key).must_be_instance_of Widescreen::Stat
42
+ end
43
+
44
+ it "returns nil if not found" do
45
+ Widescreen::Stat.find("#{@key}1").must_be_nil
46
+ end
47
+
48
+ end
49
+ end
50
+
51
+ describe "class methods" do
52
+ describe "add" do
53
+ before(:each) do
54
+ Timecop.freeze
55
+ @time = Time.now.iso8601
56
+ @metric_name = "foo"
57
+ Widescreen::Metric.create(@metric_name)
58
+ @key = [@metric_name, @time].join(Widescreen::SEPARATOR)
59
+ end
60
+
61
+ after(:each) do
62
+ Timecop.return
63
+ end
64
+
65
+ describe "when no entry for a given time" do
66
+ it "creates entry with default value" do
67
+ Widescreen::Stat.add(@metric_name)
68
+ Widescreen.redis.get(@key).must_equal "1"
69
+ end
70
+
71
+ it "creates entry with value" do
72
+ Widescreen::Stat.add(@metric_name, 5)
73
+ Widescreen.redis.get(@key).must_equal "5"
74
+ end
75
+ end
76
+
77
+ describe "when there is an entry for a given time" do
78
+ before(:each) do
79
+ Widescreen::Stat.add(@metric_name, 5)
80
+ end
81
+
82
+ it "updates entry with default value" do
83
+ Widescreen::Stat.add(@metric_name)
84
+ Widescreen.redis.get(@key).must_equal "6"
85
+ end
86
+
87
+ it "updates entry with value" do
88
+ Widescreen::Stat.add(@metric_name, 5)
89
+ Widescreen.redis.get(@key).must_equal "10"
90
+ end
91
+
92
+ end
93
+
94
+ end
95
+ end
96
+
97
+ end
@@ -0,0 +1,26 @@
1
+ # encoding: utf-8
2
+
3
+ $:.unshift File.expand_path('../lib', __FILE__)
4
+ require 'widescreen/version'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "widescreen"
8
+ s.version = Widescreen::VERSION
9
+ s.authors = ["Marcin Ciunelis"]
10
+ s.email = "marcin.ciunelis@gmail.com"
11
+ s.homepage = "http://github.com/martinciu/widescreen"
12
+ s.summary = "Rack based event statistic framework for any Rack app"
13
+
14
+ s.files = `git ls-files`.split("\n")
15
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
+ s.require_paths = ["lib"]
18
+ s.platform = Gem::Platform::RUBY
19
+
20
+ s.add_dependency 'redis', '~> 2.2.2'
21
+ s.add_dependency 'redis-namespace', '~> 1.0.3'
22
+ s.add_development_dependency 'rake'
23
+ s.add_development_dependency 'minitest', '~> 2.6.1'
24
+ s.add_development_dependency 'timecop', '~> 0.3.5'
25
+
26
+ end
metadata ADDED
@@ -0,0 +1,124 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: widescreen
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Marcin Ciunelis
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-10-21 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: redis
16
+ requirement: &2162119200 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 2.2.2
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *2162119200
25
+ - !ruby/object:Gem::Dependency
26
+ name: redis-namespace
27
+ requirement: &2162118580 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 1.0.3
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *2162118580
36
+ - !ruby/object:Gem::Dependency
37
+ name: rake
38
+ requirement: &2162118160 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *2162118160
47
+ - !ruby/object:Gem::Dependency
48
+ name: minitest
49
+ requirement: &2162117460 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 2.6.1
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *2162117460
58
+ - !ruby/object:Gem::Dependency
59
+ name: timecop
60
+ requirement: &2162096100 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ~>
64
+ - !ruby/object:Gem::Version
65
+ version: 0.3.5
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *2162096100
69
+ description:
70
+ email: marcin.ciunelis@gmail.com
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files: []
74
+ files:
75
+ - .gitignore
76
+ - .travis.yml
77
+ - Gemfile
78
+ - LICENSE
79
+ - README.md
80
+ - Rakefile
81
+ - lib/widescreen.rb
82
+ - lib/widescreen/metric.rb
83
+ - lib/widescreen/stat.rb
84
+ - lib/widescreen/version.rb
85
+ - spec/redis-test.conf
86
+ - spec/spec_helper.rb
87
+ - spec/widescreen/metric_spec.rb
88
+ - spec/widescreen/stat_spec.rb
89
+ - widescreen.gemspec
90
+ homepage: http://github.com/martinciu/widescreen
91
+ licenses: []
92
+ post_install_message:
93
+ rdoc_options: []
94
+ require_paths:
95
+ - lib
96
+ required_ruby_version: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ segments:
103
+ - 0
104
+ hash: 225638225036064920
105
+ required_rubygems_version: !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ! '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ segments:
112
+ - 0
113
+ hash: 225638225036064920
114
+ requirements: []
115
+ rubyforge_project:
116
+ rubygems_version: 1.8.10
117
+ signing_key:
118
+ specification_version: 3
119
+ summary: Rack based event statistic framework for any Rack app
120
+ test_files:
121
+ - spec/redis-test.conf
122
+ - spec/spec_helper.rb
123
+ - spec/widescreen/metric_spec.rb
124
+ - spec/widescreen/stat_spec.rb