~egoday/+junk/ftpbox

« back to all changes in this revision

Viewing changes to vendor/plugins/upload_progress/lib/.svn/text-base/progress.rb.svn-base

  • Committer: Emiliano Goday Caneda
  • Date: 2008-10-15 07:48:22 UTC
  • Revision ID: egoday@gmail.com-20081015074822-j8bn7j01fj7zf2gb
Inicial 2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
module UploadProgress #:nodoc:
 
2
  # Upload Progress abstracts the progress of an upload.  It's used by the
 
3
  # multipart progress IO that keeps track of the upload progress and creating
 
4
  # the application depends on.  It contians methods to update the progress
 
5
  # during an upload and read the statistics such as +received_bytes+,
 
6
  # +total_bytes+, +completed_percent+, +bitrate+, and
 
7
  # +remaining_seconds+
 
8
  #
 
9
  # You can get the current +Progress+ object by calling +upload_progress+ instance
 
10
  # method in your controller or view.
 
11
  #
 
12
  class Progress
 
13
    unless const_defined? :MIN_SAMPLE_TIME
 
14
      # Number of seconds between bitrate samples.  Updates that occur more
 
15
      # frequently than +MIN_SAMPLE_TIME+ will not be queued until this
 
16
      # time passes.  This behavior gives a good balance of accuracy and load
 
17
      # for both fast and slow transfers.
 
18
      MIN_SAMPLE_TIME = 0.150
 
19
 
 
20
      # Number of seconds between updates before giving up to try and calculate
 
21
      # bitrate anymore
 
22
      MIN_STALL_TIME = 10.0   
 
23
 
 
24
      # Number of samples used to calculate bitrate
 
25
      MAX_SAMPLES = 20         
 
26
    end
 
27
 
 
28
    # Number bytes received from the multipart post
 
29
    attr_reader :received_bytes
 
30
    
 
31
    # Total number of bytes expected from the mutlipart post
 
32
    attr_reader :total_bytes
 
33
    
 
34
    # The last time the upload history was updated
 
35
    attr_reader :last_update_time
 
36
 
 
37
    # A message you can set from your controller or view to be rendered in the 
 
38
    # +upload_status_text+ helper method.  If you set a messagein a controller
 
39
    # then call <code>session.update</code> to make that message available to 
 
40
    # your +upload_status+ action.
 
41
    attr_accessor :message
 
42
 
 
43
    # Create a new Progress object passing the expected number of bytes to receive
 
44
    def initialize(total)
 
45
      @total_bytes = total
 
46
      reset!
 
47
    end
 
48
 
 
49
    # Resets the received_bytes, last_update_time, message and bitrate, but 
 
50
    # but maintains the total expected bytes
 
51
    def reset!
 
52
      @received_bytes, @last_update_time, @stalled, @message = 0, 0, false, ''
 
53
      reset_history
 
54
    end
 
55
 
 
56
    # Number of bytes left for this upload
 
57
    def remaining_bytes
 
58
      @total_bytes - @received_bytes
 
59
    end
 
60
 
 
61
    # Completed percent in integer form from 0..100
 
62
    def completed_percent
 
63
      (@received_bytes * 100 / @total_bytes).to_i rescue 0
 
64
    end
 
65
 
 
66
    # Updates this UploadProgress object with the number of bytes received
 
67
    # since last update time and the absolute number of seconds since the
 
68
    # beginning of the upload.
 
69
    # 
 
70
    # This method is used by the +MultipartProgress+ module and should
 
71
    # not be called directly.
 
72
    def update!(bytes, elapsed_seconds)#:nodoc:
 
73
      if @received_bytes + bytes > @total_bytes
 
74
        #warn "Progress#update received bytes exceeds expected bytes"
 
75
        bytes = @total_bytes - @received_bytes
 
76
      end
 
77
 
 
78
      @received_bytes += bytes
 
79
 
 
80
      # Age is the duration of time since the last update to the history
 
81
      age = elapsed_seconds - @last_update_time
 
82
 
 
83
      # Record the bytes received in the first element of the history
 
84
      # in case the sample rate is exceeded and we shouldn't record at this
 
85
      # time
 
86
      @history.first[0] += bytes
 
87
      @history.first[1] += age
 
88
 
 
89
      history_age = @history.first[1]
 
90
 
 
91
      @history.pop while @history.size > MAX_SAMPLES
 
92
      @history.unshift([0,0]) if history_age > MIN_SAMPLE_TIME
 
93
 
 
94
      if history_age > MIN_STALL_TIME
 
95
        @stalled = true
 
96
        reset_history 
 
97
      else
 
98
        @stalled = false
 
99
      end
 
100
 
 
101
      @last_update_time = elapsed_seconds
 
102
      
 
103
      self
 
104
    end
 
105
 
 
106
    # Calculates the bitrate in bytes/second. If the transfer is stalled or
 
107
    # just started, the bitrate will be 0
 
108
    def bitrate
 
109
      history_bytes, history_time = @history.transpose.map { |vals| vals.inject { |sum, v| sum + v } } 
 
110
      history_bytes / history_time rescue 0
 
111
    end
 
112
 
 
113
    # Number of seconds elapsed since the start of the upload
 
114
    def elapsed_seconds
 
115
      @last_update_time
 
116
    end
 
117
 
 
118
    # Calculate the seconds remaining based on the current bitrate. Returns
 
119
    # O seconds if stalled or if no bytes have been received
 
120
    def remaining_seconds
 
121
      remaining_bytes / bitrate rescue 0
 
122
    end
 
123
 
 
124
    # Returns true if there are bytes pending otherwise returns false
 
125
    def finished?
 
126
      remaining_bytes <= 0
 
127
    end
 
128
 
 
129
    # Returns true if some bytes have been received
 
130
    def started?
 
131
      @received_bytes > 0
 
132
    end
 
133
 
 
134
    # Returns true if there has been a delay in receiving bytes.  The delay
 
135
    # is set by the constant MIN_STALL_TIME
 
136
    def stalled?
 
137
      @stalled
 
138
    end
 
139
 
 
140
    private
 
141
    def reset_history
 
142
      @history = [[0,0]]
 
143
    end
 
144
  end
 
145
end