2010-06-22 22 views
10

Zajmuję się tworzeniem aplikacji Sinatra, która składa się z formularza do przesyłania, z paskiem postępu wskazującym, ile załadunku zostało ukończone. Proces, jak opisany przez ryan dahl, jest następujący:Sinatra, pasek postępu w formularzu przesyłania

HTTP przesłać paski postępu są raczej obfuscated- one zazwyczaj obejmować proces uruchomiony na serwerze śledzenie rozmiaru pliku tymczasowego, że serwer HTTP jest pisanie do, następnie po stronie klienta wywołanie AJAX jest wykonywane co kilka sekund na serwerze podczas przesyłania, aby poprosić o postęp przesyłania.

Każdy przesyłanie ma losowy session-id i śledzić stowarzyszenia i zatrudnić class variable w mojej aplikacji (wiem, to straszne - jeśli macie lepsze pomysły, proszę mi powiedzieć)

configure do 
    @@assoc = {} 
end 

Mam trasę do przesłania POST i GET do odpytywania AJAX. Wewnątrz trasy POST zapisuję skojarzenie session-id, Tempfile i całkowity rozmiar.

post '/files' do 
    tmp = params[:file][:tempfile] 
    # from here on, @@assoc[@sid] should have a value, even in other routes 
    @@assoc[@sid] = { :file => tmp, :size => env['CONTENT_LENGTH'] } 
    File.open("#{options.filesdir}/#{filename}", 'w+') do |file| 
    file << tmp.read 
    end 
end 

W trasie GET, i obliczyć procent oparte na Tempfile „s aktualnego rozmiaru:

get '/status/:sid' do 
    h = @@assoc[params[:sid]] 
    unless h.nil? 
    percentage = (h[:file].size/h[:size].to_f) * 100 
    "#{percentage}%" 
    else 
    "0%" 
    end 
end 

Problemem jest to, że dopóki żądanie POST nie ukończył (czyli po jej Przeczytaj całość Tempfile) h.nil? zwraca true, co nie ma większego sensu, ponieważ właśnie przypisałem @@assoc[@sid] wartość na innej trasie.

Więc czego tu brakuje?

EDIT: Próbowałem

  • set :reload, false
  • set :environment, :production
  • config { @@assoc ||= {} }
  • Próbowałem też rzuca na niego db relacyjnej (SQLite z DataMapper)

Żaden nie zadziałał.

+0

W linii '@@ assoc [@ sid] = {...' brakuje '}' na końcu. – Adrian

+0

naprawiony, dzięki :) – asymmetric

Odpowiedz

4

Myślę, że mam na czym polega problem:

tmp = params[:file][:tempfile] nie wraca, dopóki plik został całkowicie odebrany.

+0

prawda, znalazłeś obejście tego problemu? – dombesz

1
@@assoc[@sid] = { :file => tmp, :size => env['CONTENT_LENGTH'] } 

powinny być

@@assoc[params[:sid]] = { :file => tmp, :size => env['CONTENT_LENGTH'] } 
+0

tak, to literówka w pytaniu, w aplikacji jest ok. dzięki mimo to za zgłoszenie. – asymmetric