Skip to content

Instantly share code, notes, and snippets.

@eagleas
Created December 16, 2011 12:58

Revisions

  1. eagleas revised this gist Dec 16, 2011. No changes.
  2. eagleas created this gist Dec 16, 2011.
    198 changes: 198 additions & 0 deletions all.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,198 @@
    #encoding: utf-8
    class File::Base < ActiveRecord::Base

    scope :shared, where(["files.shared_at IS NOT NULL AND (files.shared_at + CAST('1 hour' AS INTERVAL) * files.shared_hours > NOW())"])

    def shared=(value)
    @shared =
    if value.nil? || value == '0'
    shared_expire!
    false
    else
    self.shared_at = Time.zone.now
    self.shared_hours = self.class.value_to_hours(value.to_i)
    true
    end
    end

    def shared
    return @shared if defined?(@shared)
    shared?
    end

    def shared?
    self.shared_hours = App.shared_hours if shared_at && !shared_hours
    shared_at && shared_hours && (shared_expired_at > Time.zone.now ? true : (shared_expire!; false))
    end

    def shared_expire!
    self.class.update_all({:shared_at => nil, :shared_hours => nil}, {:id => self.id})
    end

    def shared_without_auth=(value)
    write_preference(:sh_woauth, value == '0' ? false : true)
    end
    alias_method :without_auth=, :shared_without_auth=

    def shared_expired_at
    shared_at + shared_hours.hours
    end

    def shared_expired_at=(date)
    return unless date
    @shared = true
    self.shared_at = Time.zone.now
    date = (Time.xmlschema(date) rescue date)
    self.shared_hours = ((date - shared_at)/3600).round
    end

    before_save :check_expired_at

    def check_expired_at
    if shared
    raise Files::Forbidden.new(:must_be_paid) if must_be_paid?
    else
    self.shared_at = nil
    self.shared_hours = nil
    end
    end

    # Value in range 1..50
    #
    # value | time
    # --------------
    # 1 | 1 hour
    # ... |
    # 23 | 23 hours
    # 24 | 1 day
    # ... |
    # 29 | 6 days
    # 30 | 1 week
    # ... |
    # 33 | 1 month = 30 days
    # ... |
    # 43 | 11 months
    # 44 | 1 year = 365 days
    # ... |
    # 48 | 5 years
    # 49 | 10 years
    # 50 | 100 years

    def self.value_to_hours(value)
    if value <= 24
    # hours
    value
    elsif value > 24 && value <= 30
    # days
    (value - 23)*24
    elsif value > 30 && value < 33
    # weeks
    (value - 29)*24*7
    elsif value >= 33 && value <= 43
    # months
    (value - 32)*24*30
    elsif value >= 44 && value <= 48
    # years
    (value - 43)*24*365
    elsif value == 49
    # 10 years
    24*365*10
    elsif value == 50
    # 100 years
    24*365*100
    end
    end

    def self.hours_to_value(hours)
    if hours <= 24
    hours
    elsif hours == 100*365*24
    # 100 years
    50
    elsif hours == 10*365*24
    # 10 years
    49
    elsif hours % (365*24) == 0
    # years
    hours/(24*365) + 43
    elsif hours % (30*24) == 0
    # months
    hours/(24*30) + 32
    elsif hours % (7*24) == 0
    # weeks
    hours/(24*7) + 29
    elsif hours % 24 == 0
    # days
    hours/24 + 23
    end
    end

    def self.hours_to_value2(hours)
    a = (1..50).to_a.map {|i| self.value_to_hours(i)}
    a2 = a.detect{|i| i > hours}
    a1 = a.reverse.detect{|i| i < hours}
    self.hours_to_value( (hours - a1) >= (a2 - hours) ? a2 : a1 )
    end

    end

    #encoding: utf-8

    describe File::Base do

    context "value_to_hours and back" do
    (1..24).to_a.each do |i|
    it 'hours 'do
    File::Base.value_to_hours(i).should == i
    File::Base.hours_to_value(i).should == i
    end
    end
    (24..30).to_a.each do |i|
    it 'days' do
    File::Base.value_to_hours(i).should == (i-23)*24
    File::Base.hours_to_value((i-23)*24).should == i
    end
    end
    (30..32).to_a.each do |i|
    it 'weeks' do
    File::Base.value_to_hours(i).should == (i-29)*24*7
    File::Base.hours_to_value((i-29)*24*7).should == i
    end
    end
    (33..43).to_a.each do |i|
    it 'months' do
    File::Base.value_to_hours(i).should == (i-32)*24*30
    File::Base.hours_to_value((i-32)*24*30).should == i
    end
    end
    (44..48).to_a.each do |i|
    it 'years' do
    File::Base.value_to_hours(i).should == (i-43)*24*365
    File::Base.hours_to_value((i-43)*24*365).should == i
    end
    end
    it 'value = 49' do
    File::Base.value_to_hours(49).should == 24*365*10
    File::Base.hours_to_value(24*365*10).should == 49
    end
    it 'value = 50' do
    File::Base.value_to_hours(50).should == 24*365*100
    File::Base.hours_to_value(24*365*100).should == 50
    end

    context 'unrounded hours to rounded to value' do
    [ # hours, value
    [25, 24], # 25 hours => 1 day
    [36, 25], # 1,5 days => 2 days
    [49, 25], # 2d+1h => 2d
    [156, 30], # 6,5d => 1w
    [169, 30], # 7d+1h => 7d
    [8280, 43] # 11,5m => 11m # 7920h < 8280h < 8760h
    ].each do |i|
    it do File::Base.hours_to_value2(i[0]).should == i[1]; end
    end
    end

    end

    end