Commit 6f15c634910c660e6b8e40a3eb6ed37283f9168f

Authored by Fernando Brito
1 parent f8418da0
Exists in master and in 2 other branches v2, wikilibras

Websocket-rails

Move js files to right path
Videos#delete
@@ -18,6 +18,8 @@ gem 'uglifier', '>= 1.3.0' @@ -18,6 +18,8 @@ gem 'uglifier', '>= 1.3.0'
18 gem 'coffee-rails', '~> 4.0.0' 18 gem 'coffee-rails', '~> 4.0.0'
19 gem 'jquery-rails' 19 gem 'jquery-rails'
20 gem 'therubyracer', :platform => :ruby 20 gem 'therubyracer', :platform => :ruby
  21 +gem 'websocket-rails'
  22 +
21 # gem 'turbolinks' 23 # gem 'turbolinks'
22 24
23 gem 'devise' 25 gem 'devise'
@@ -117,6 +117,8 @@ GEM @@ -117,6 +117,8 @@ GEM
117 warden (~> 1.2.3) 117 warden (~> 1.2.3)
118 diff-lcs (1.2.5) 118 diff-lcs (1.2.5)
119 dotenv (0.7.0) 119 dotenv (0.7.0)
  120 + em-synchrony (1.0.3)
  121 + eventmachine (>= 1.0.0.beta.1)
120 em-websocket (0.5.1) 122 em-websocket (0.5.1)
121 eventmachine (>= 0.12.9) 123 eventmachine (>= 0.12.9)
122 http_parser.rb (~> 0.6.0) 124 http_parser.rb (~> 0.6.0)
@@ -130,6 +132,9 @@ GEM @@ -130,6 +132,9 @@ GEM
130 railties (>= 3.0.0) 132 railties (>= 3.0.0)
131 faker (1.3.0) 133 faker (1.3.0)
132 i18n (~> 0.5) 134 i18n (~> 0.5)
  135 + faye-websocket (0.7.3)
  136 + eventmachine (>= 0.12.0)
  137 + websocket-driver (>= 0.3.1)
133 ffi (1.9.3) 138 ffi (1.9.3)
134 foreman (0.66.0) 139 foreman (0.66.0)
135 dotenv (~> 0.7.0) 140 dotenv (~> 0.7.0)
@@ -166,6 +171,7 @@ GEM @@ -166,6 +171,7 @@ GEM
166 actionpack (>= 3.2, < 5) 171 actionpack (>= 3.2, < 5)
167 activesupport (>= 3.2, < 5) 172 activesupport (>= 3.2, < 5)
168 hike (1.2.3) 173 hike (1.2.3)
  174 + hiredis (0.5.2)
169 hpricot (0.8.6) 175 hpricot (0.8.6)
170 html2haml (1.0.1) 176 html2haml (1.0.1)
171 erubis (~> 2.7.0) 177 erubis (~> 2.7.0)
@@ -276,6 +282,9 @@ GEM @@ -276,6 +282,9 @@ GEM
276 rb-fsevent (0.9.4) 282 rb-fsevent (0.9.4)
277 rb-inotify (0.9.4) 283 rb-inotify (0.9.4)
278 ffi (>= 0.5.0) 284 ffi (>= 0.5.0)
  285 + redis (3.0.7)
  286 + redis-objects (0.9.1)
  287 + redis (>= 3.0.2)
279 responders (1.0.0) 288 responders (1.0.0)
280 railties (>= 3.2, < 5) 289 railties (>= 3.2, < 5)
281 rolify (3.4.0) 290 rolify (3.4.0)
@@ -363,6 +372,16 @@ GEM @@ -363,6 +372,16 @@ GEM
363 warden (1.2.3) 372 warden (1.2.3)
364 rack (>= 1.0) 373 rack (>= 1.0)
365 websocket (1.0.7) 374 websocket (1.0.7)
  375 + websocket-driver (0.3.3)
  376 + websocket-rails (0.7.0)
  377 + em-synchrony
  378 + faye-websocket
  379 + hiredis
  380 + rack
  381 + rails
  382 + redis
  383 + redis-objects
  384 + thin
366 xpath (2.0.0) 385 xpath (2.0.0)
367 nokogiri (~> 1.3) 386 nokogiri (~> 1.3)
368 387
@@ -419,3 +438,4 @@ DEPENDENCIES @@ -419,3 +438,4 @@ DEPENDENCIES
419 thin 438 thin
420 twitter-bootstrap-rails 439 twitter-bootstrap-rails
421 uglifier (>= 1.3.0) 440 uglifier (>= 1.3.0)
  441 + websocket-rails
app/admin/v_libras_video.rb
1 ActiveAdmin.register VLibras::Video do 1 ActiveAdmin.register VLibras::Video do
2 menu :priority => 15 2 menu :priority => 15
3 -  
4 - # See permitted parameters documentation:  
5 - # https://github.com/gregbell/active_admin/blob/master/docs/2-resource-customization.md#setting-up-strong-parameters  
6 - #  
7 - # permit_params :list, :of, :attributes, :on, :model  
8 - #  
9 - # or  
10 - #  
11 - # permit_params do  
12 - # permitted = [:permitted, :attributes]  
13 - # permitted << :other if resource.something?  
14 - # permitted  
15 - # end  
16 - 3 +
  4 + permit_params :url, :request_id
17 end 5 end
app/assets/javascripts/application.js
@@ -13,4 +13,5 @@ @@ -13,4 +13,5 @@
13 //= require jquery 13 //= require jquery
14 //= require jquery_ujs 14 //= require jquery_ujs
15 //= require twitter/bootstrap 15 //= require twitter/bootstrap
16 -//= require_tree . 16 +//= require websocket_rails/main
  17 +
app/assets/javascripts/static/v_libras/rapid.js
@@ -1,26 +0,0 @@ @@ -1,26 +0,0 @@
1 -$(function() {  
2 - $("#service-video").click(function() {  
3 - console.log($(this).prop('defaultChecked'));  
4 -  
5 - $("#url").show('slow');  
6 - $("#legend").hide('slow');  
7 - });  
8 -  
9 - $("#service-video-subtitle").click(function() {  
10 - console.log($(this).prop('defaultChecked'));  
11 -  
12 - $("#url").show('slow');  
13 - $("#legend").show('slow');  
14 - });  
15 -  
16 - /* When user press "Back" on the browser */  
17 - if ($("#service-video-subtitle")[0].checked) {  
18 - console.log('b');  
19 - $("#service-video-subtitle").click();  
20 - }  
21 -  
22 - if ($("#service-video")[0].checked) {  
23 - console.log('a');  
24 - $("#service-video").click();  
25 - }  
26 -});  
27 \ No newline at end of file 0 \ No newline at end of file
app/assets/javascripts/v_libras/requests/rapid.js 0 → 100644
@@ -0,0 +1,20 @@ @@ -0,0 +1,20 @@
  1 +$(function() {
  2 + $("#service-video").click(function() {
  3 + $("#url").show('slow');
  4 + $("#legend").hide('slow');
  5 + });
  6 +
  7 + $("#service-video-subtitle").click(function() {
  8 + $("#url").show('slow');
  9 + $("#legend").show('slow');
  10 + });
  11 +
  12 + /* When user press "Back" on the browser */
  13 + if ($("#service-video-subtitle")[0].checked) {
  14 + $("#service-video-subtitle").click();
  15 + }
  16 +
  17 + if ($("#service-video")[0].checked) {
  18 + $("#service-video").click();
  19 + }
  20 +});
0 \ No newline at end of file 21 \ No newline at end of file
app/assets/javascripts/v_libras/videos/index.js 0 → 100644
@@ -0,0 +1,16 @@ @@ -0,0 +1,16 @@
  1 +$(function() {
  2 + $("a.badge").tooltip();
  3 +
  4 + // connect to server like normal
  5 + // FIXME: how to get the right address
  6 + var dispatcher = new WebSocketRails('localhost:3000/websocket');
  7 +
  8 + // subscribe to the channel
  9 + var channel = dispatcher.subscribe('requests_update');
  10 +
  11 + // bind to a channel event
  12 + channel.bind('update', function(data) {
  13 + alert("channel updated");
  14 + location.reload();
  15 + });
  16 +});
0 \ No newline at end of file 17 \ No newline at end of file
app/assets/stylesheets/bootstrap_overrides.css.scss
@@ -43,4 +43,9 @@ @@ -43,4 +43,9 @@
43 } 43 }
44 .breadcrumb .active a { 44 .breadcrumb .active a {
45 color: #333333; 45 color: #333333;
  46 +}
  47 +
  48 +.login {
  49 + padding: 3% 5%;
  50 + margin: 10px 35% 30px;
46 } 51 }
47 \ No newline at end of file 52 \ No newline at end of file
app/controllers/v_libras/videos_controller.rb
1 -class VLibras::VideosController < ApplicationController 1 +class VLibras::VideosController < InheritedResources::Base
  2 + actions :destroy
  3 +
2 before_filter :check_vlibras_api_status, :only => [ :index ] 4 before_filter :check_vlibras_api_status, :only => [ :index ]
3 5
4 def index 6 def index
5 @videos = current_user.videos 7 @videos = current_user.videos
6 - @requests = current_user.requests.limit(10) 8 + @requests = current_user.requests.limit(6)
7 end 9 end
8 end 10 end
app/helpers/application_helper.rb
@@ -27,20 +27,23 @@ module ApplicationHelper @@ -27,20 +27,23 @@ module ApplicationHelper
27 end 27 end
28 end 28 end
29 29
30 - def request_status_label(status)  
31 - classes = [ 'label' ] 30 + def request_status_label(request)
  31 + classes = [ 'badge' ]
  32 +
  33 + status = request.status
32 34
33 case status 35 case status
34 when 'created' 36 when 'created'
35 when 'processing' 37 when 'processing'
36 - classes << 'label-warning' 38 + classes << 'badge-warning'
37 when 'error' 39 when 'error'
38 - classes << 'label-important' 40 + classes << 'badge-important'
39 when 'success' 41 when 'success'
40 - classes << 'label-success' 42 + classes << 'badge-success'
41 end 43 end
42 44
43 - content_tag(:div, t(status, scope: 'status'), :class => classes) 45 + content_tag(:a, t(status, scope: 'status'), :class => classes,
  46 + :data => { 'toggle' => "tooltip" }, :title => request.response)
44 end 47 end
45 48
46 end 49 end
app/models/v_libras/request.rb
@@ -19,7 +19,7 @@ class VLibras::Request &lt; ActiveRecord::Base @@ -19,7 +19,7 @@ class VLibras::Request &lt; ActiveRecord::Base
19 19
20 belongs_to :owner, :class => User 20 belongs_to :owner, :class => User
21 21
22 - has_one :video, :class => VLibras::Video 22 + has_one :video, :class => VLibras::Video, :dependent => :destroy
23 23
24 validates :service_type, 24 validates :service_type,
25 presence: true, 25 presence: true,
app/models/v_libras/video.rb
@@ -10,5 +10,5 @@ @@ -10,5 +10,5 @@
10 # 10 #
11 11
12 class VLibras::Video < ActiveRecord::Base 12 class VLibras::Video < ActiveRecord::Base
13 - belongs_to :request, :class => VLibras::Request 13 + belongs_to :request, :class => VLibras::Request, :dependent => :delete
14 end 14 end
app/views/layouts/application.html.erb
@@ -4,6 +4,7 @@ @@ -4,6 +4,7 @@
4 <title>GTAaaS</title> 4 <title>GTAaaS</title>
5 <%= stylesheet_link_tag "application", :media => "all" %> 5 <%= stylesheet_link_tag "application", :media => "all" %>
6 <%= javascript_include_tag "application" %> 6 <%= javascript_include_tag "application" %>
  7 + <%= yield :js %>
7 <%= csrf_meta_tags %> 8 <%= csrf_meta_tags %>
8 </head> 9 </head>
9 <body> 10 <body>
app/views/v_libras/requests/rapid.haml
1 -= javascript_include_tag "static/v_libras/rapid" 1 +- content_for :js do
  2 + = javascript_include_tag "v_libras/requests/rapid"
2 3
3 .login 4 .login
4 %h2 5 %h2
app/views/v_libras/videos/index.haml
  1 +- content_for :js do
  2 + = javascript_include_tag "v_libras/videos/index"
  3 +
1 .breadcrumb 4 .breadcrumb
2 %h3= t('videos.list') 5 %h3= t('videos.list')
3 6
@@ -7,7 +10,8 @@ @@ -7,7 +10,8 @@
7 = link_to image_tag("avatar.png"), video.url 10 = link_to image_tag("avatar.png"), video.url
8 %p 11 %p
9 = link_to t('videos.show'), video_path(video), class: "btn btn-success" 12 = link_to t('videos.show'), video_path(video), class: "btn btn-success"
10 - = link_to t('videos.delete'), video_path(video), confirm: t('shared.confirm_delete'), method: :delete, class: "btn btn-danger" 13 + = link_to t('videos.delete'), v_libras_video_path(video), method: :delete,
  14 + class: "btn btn-danger", data: { confirm: t('shared.confirm_delete') }
11 15
12 .breadcrumb.requests 16 .breadcrumb.requests
13 %h4= t('requests.list') 17 %h4= t('requests.list')
@@ -22,7 +26,7 @@ @@ -22,7 +26,7 @@
22 26
23 - @requests.each do |request| 27 - @requests.each do |request|
24 %tr 28 %tr
25 - %td.span2= request_status_label(request.status) 29 + %td.span2= request_status_label(request)
26 %td.span5= request.video_filename 30 %td.span5= request.video_filename
27 %td.span5= time_ago_in_words(request.created_at) 31 %td.span5= time_ago_in_words(request.created_at)
28 32
config/environments/development.rb
@@ -56,4 +56,7 @@ Rails.application.configure do @@ -56,4 +56,7 @@ Rails.application.configure do
56 config.action_view.raise_on_missing_translations = true 56 config.action_view.raise_on_missing_translations = true
57 57
58 config.middleware.use Rack::LiveReload 58 config.middleware.use Rack::LiveReload
  59 +
  60 + # websocket-rails
  61 + config.middleware.delete Rack::Lock
59 end 62 end
config/events.rb 0 → 100644
@@ -0,0 +1,14 @@ @@ -0,0 +1,14 @@
  1 +WebsocketRails::EventMap.describe do
  2 + # You can use this file to map incoming events to controller actions.
  3 + # One event can be mapped to any number of controller actions. The
  4 + # actions will be executed in the order they were subscribed.
  5 + #
  6 + # Uncomment and edit the next line to handle the client connected event:
  7 + # subscribe :client_connected, :to => Controller, :with_method => :method_name
  8 + #
  9 + # Here is an example of mapping namespaced events:
  10 + # namespace :product do
  11 + # subscribe :new, :to => ProductController, :with_method => :new_product
  12 + # end
  13 + # The above will handle an event triggered on the client like `product.new`.
  14 +end
config/initializers/assets.rb
1 -Rails.application.config.assets.precompile += %w( static/v_libras/rapid.js )  
2 \ No newline at end of file 1 \ No newline at end of file
  2 +Rails.application.config.assets.precompile += %w( v_libras/requests/rapid.js )
  3 +Rails.application.config.assets.precompile += %w( v_libras/videos/index.js )
3 \ No newline at end of file 4 \ No newline at end of file
config/initializers/websocket_rails.rb 0 → 100644
@@ -0,0 +1,63 @@ @@ -0,0 +1,63 @@
  1 +WebsocketRails.setup do |config|
  2 +
  3 + # Uncomment to override the default log level. The log level can be
  4 + # any of the standard Logger log levels. By default it will mirror the
  5 + # current Rails environment log level.
  6 + config.log_level = :debug
  7 +
  8 + # Uncomment to change the default log file path.
  9 + # config.log_path = "#{Rails.root}/log/websocket_rails.log"
  10 +
  11 + # Set to true if you wish to log the internal websocket_rails events
  12 + # such as the keepalive `websocket_rails.ping` event.
  13 + # config.log_internal_events = false
  14 +
  15 + # Change to true to enable standalone server mode
  16 + # Start the standalone server with rake websocket_rails:start_server
  17 + # * Requires Redis
  18 + config.standalone = false
  19 +
  20 + # Change to true to enable channel synchronization between
  21 + # multiple server instances.
  22 + # * Requires Redis.
  23 + config.synchronize = false
  24 +
  25 + # Prevent Thin from daemonizing (default is true)
  26 + # config.daemonize = false
  27 +
  28 + # Uncomment and edit to point to a different redis instance.
  29 + # Will not be used unless standalone or synchronization mode
  30 + # is enabled.
  31 + # config.redis_options = {:host => 'localhost', :port => '6379'}
  32 +
  33 + # By default, all subscribers in to a channel will be removed
  34 + # when that channel is made private. If you don't wish active
  35 + # subscribers to be removed from a previously public channel
  36 + # when making it private, set the following to true.
  37 + # config.keep_subscribers_when_private = false
  38 +
  39 + # Set to true if you wish to broadcast channel subscriber_join and
  40 + # subscriber_part events. All subscribers of a channel will be
  41 + # notified when other clients join and part the channel. If you are
  42 + # using the UserManager, the current_user object will be sent along
  43 + # with the event.
  44 + # config.broadcast_subscriber_events = true
  45 +
  46 + # Used as the key for the WebsocketRails.users Hash. This method
  47 + # will be called on the `current_user` object in your controller
  48 + # if one exists. If `current_user` does not exist or does not
  49 + # respond to the identifier, the key will default to `connection.id`
  50 + # config.user_identifier = :id
  51 +
  52 + # Uncomment and change this option to override the class associated
  53 + # with your `current_user` object. This class will be used when
  54 + # synchronization is enabled and you trigger events from background
  55 + # jobs using the WebsocketRails.users UserManager.
  56 + # config.user_class = User
  57 +
  58 + # Supporting HTTP streaming on Internet Explorer versions 8 & 9
  59 + # requires CORS to be enabled for GET "/websocket" request.
  60 + # List here the origin domains allowed to perform the request.
  61 + # config.allowed_origins = ['http://localhost:3000']
  62 +
  63 +end
config/routes.rb
@@ -17,7 +17,7 @@ Rails.application.routes.draw do @@ -17,7 +17,7 @@ Rails.application.routes.draw do
17 post 'callback', on: :collection 17 post 'callback', on: :collection
18 end 18 end
19 19
20 - resources :videos, :only => [ :index ] 20 + resources :videos, :only => [ :index, :destroy ]
21 21
22 22
23 end 23 end
lib/api_client/callback_processor.rb
1 class ApiClient::CallbackProcessor 1 class ApiClient::CallbackProcessor
2 def self.process(params) 2 def self.process(params)
3 request = VLibras::Request.find(params[:request_id]) 3 request = VLibras::Request.find(params[:request_id])
4 - request.update(:status => 'success')  
5 - request.create_video(:url => params['response']) 4 +
  5 + if params['error']
  6 + Rails.logger.debug "[VLibras::Callback]: Error #{params}"
  7 +
  8 + request.update!(:status => 'error', :response => params['error'])
  9 + else
  10 + Rails.logger.debug "[VLibras::Callback] OK: #{params}"
  11 +
  12 + request.update!(:status => 'success')
  13 + request.create_video(:url => params['response'])
  14 + end
  15 +
  16 + Rails.logger.debug "[VLibras::Callback] Notifying websocket channel"
  17 + WebsocketRails[:requests_update].trigger(:update, {a: :b, c: :d})
6 end 18 end
7 end 19 end
8 \ No newline at end of file 20 \ No newline at end of file
lib/api_client/client.rb
@@ -7,7 +7,7 @@ module ApiClient::Client @@ -7,7 +7,7 @@ module ApiClient::Client
7 def self.submit(request, files) 7 def self.submit(request, files)
8 o = { query: request.params.clone } 8 o = { query: request.params.clone }
9 o[:query].merge!({ :servico => request.service_type }) 9 o[:query].merge!({ :servico => request.service_type })
10 - o[:query].merge!({ :callback => "http://150.165.205.192:3000/v_libras/requests/callback?request_id=#{request.id}" }) 10 + o[:query].merge!({ :callback => "http://150.165.205.166:3000/v_libras/requests/callback?request_id=#{request.id}" })
11 11
12 o[:query].merge!({ :video => files[:video].file.to_file }) 12 o[:query].merge!({ :video => files[:video].file.to_file })
13 13
@@ -27,8 +27,12 @@ module ApiClient::Client @@ -27,8 +27,12 @@ module ApiClient::Client
27 else 27 else
28 request.update!(:response => response.body, :status => 'error') 28 request.update!(:response => response.body, :status => 'error')
29 end 29 end
30 - rescue  
31 - 30 + rescue => e
  31 + request.update!(:status => 'error', :response => e)
  32 + ensure
  33 + # FIXME: Running on another thread. Websocket not working :(
  34 + Delayed::Worker.logger.debug "[VLibras::Request] Sending message to websocket channel"
  35 + WebsocketRails[:requests_update].trigger(:update, {a: :b, c: :d})
32 end 36 end
33 37
34 private 38 private