lib/monocle.rb in monocle-0.1.1 vs lib/monocle.rb in monocle-0.2.0

- old
+ new

@@ -1,11 +1,79 @@ +require 'active_support/concern' +require 'active_support/core_ext' +require 'redis' + +require 'monocle/core_ext' + module Monocle - autoload :Server, "monocle/server" - autoload :Views, "monocle/views" + extend ActiveSupport::Concern - autoload :View, "monocle/view" - autoload :OverallView, "monocle/overall_view" - autoload :DailyView, "monocle/daily_view" - autoload :WeeklyView, "monocle/weekly_view" - autoload :MonthlyView, "monocle/monthly_view" - autoload :YearlyView, "monocle/yearly_view" + included do + class_attribute :_monocle_options, + :_monocle_view_types, + :_monocle_redis_connection + + self._monocle_options = { + cache_view_counts: false + } + + self._monocle_view_types = { + overall: -> { 'overall' }, + yearly: -> { Time.now.beginning_of_year }, + monthly: -> { Time.now.beginning_of_month }, + weekly: -> { Time.now.beginning_of_week }, + daily: -> { Time.now.beginning_of_day }, + hourly: -> { Time.now.beginning_of_hour } + } + + self._monocle_redis_connection = Redis.new || REDIS + end + + module ClassMethods + def monocle_key(*append) + extra = (append.empty?) ? '' : ':' + append.join(':') + "monocle:#{self.to_s.underscore}" + extra + end + + def monocle_options(options = {}) + self._monocle_options = self._monocle_options.merge(options) + end + + def monocle_views(types = {}) + self._monocle_view_types = types + self._monocle_view_types.each do |k,v| + define_method("#{k}_views_count") do + self._monocle_redis_connection.hget(self.class.monocle_key(id), self.send("#{k}_views_field")).to_i || 0 + end + + define_method("#{k}_views_field") do + field = v.call + field.is_a?(String) ? field : field.to_i + end + end + end + + def most_viewed_since(since, limit = 1000) + objects = self._monocle_redis_connection.zrevrangebyscore(self.monocle_key, Time.now.to_i, since.to_i, limit: [0, limit]) + objects.collect { |o| self.find(o[0]) } + end + end + + def view! + self._monocle_view_types.keys.each do |view_type| + cache_field = "#{view_type}_views".to_sym + count = self._monocle_redis_connection.hincrby(self.class.monocle_key(id), self.send("#{view_type}_views_field"), 1) + if self._monocle_options[:cache_view_counts] && respond_to?(cache_field) + update_column(cache_field, count) if respond_to?(:update_column) + set(cache_field, count) if respond_to?(:set) + end + end + + self._monocle_redis_connection.zadd(self.class.monocle_key, Time.now.to_i, id) + end + + def destroy_views + self._monocle_redis_connection.del(self.class.monocle_key(id)) + end + + autoload :Server, 'monocle/server' end