diff --git a/admin/config/application.rb b/admin/config/application.rb index 0e13be779..eb5c1c612 100644 --- a/admin/config/application.rb +++ b/admin/config/application.rb @@ -110,6 +110,7 @@ module JamAdmin config.redis_host = "localhost:6379" + config.email_social_alias = 'social@jamkazam.com' config.email_alerts_alias = 'alerts@jamkazam.com' # should be used for 'oh no' server down/service down sorts of emails config.email_generic_from = 'nobody@jamkazam.com' config.email_smtp_address = 'smtp.sendgrid.net' diff --git a/admin/config/environments/development.rb b/admin/config/environments/development.rb index b449898e8..8ae1ae4ed 100644 --- a/admin/config/environments/development.rb +++ b/admin/config/environments/development.rb @@ -46,4 +46,5 @@ JamAdmin::Application.configure do config.email_generic_from = 'nobody-dev@jamkazam.com' config.email_alerts_alias = 'alerts-dev@jamkazam.com' + config.email_social_alias = 'social-dev@jamkazam.com' end diff --git a/db/up/video_recording.sql b/db/up/video_recording.sql index 44a976d30..46502b104 100644 --- a/db/up/video_recording.sql +++ b/db/up/video_recording.sql @@ -1 +1,3 @@ -ALTER TABLE recordings ADD video BOOLEAN NOT NULL DEFAULT FALSE; \ No newline at end of file +ALTER TABLE recordings ADD video BOOLEAN NOT NULL DEFAULT FALSE; +ALTER TABLE user_authorizations ADD refresh_token VARCHAR; +ALTER TABLE recordings ADD external_video_id VARCHAR; \ No newline at end of file diff --git a/ruby/lib/jam_ruby/app/mailers/admin_mailer.rb b/ruby/lib/jam_ruby/app/mailers/admin_mailer.rb index f14d8e424..abe1b9564 100644 --- a/ruby/lib/jam_ruby/app/mailers/admin_mailer.rb +++ b/ruby/lib/jam_ruby/app/mailers/admin_mailer.rb @@ -1,6 +1,6 @@ module JamRuby # sends out a boring ale - class AdminMailer < ActionMailer::Base + class AdminMailer < ActionMailer::Base include SendGrid @@ -20,6 +20,14 @@ module JamRuby subject: options[:subject]) end + def social(options) + mail(to: APP_CONFIG.email_social_alias, + from: APP_CONFIG.email_generic_from, + body: options[:body], + content_type: "text/plain", + subject: options[:subject]) + end + def recurly_alerts(user, options) body = options[:body] diff --git a/ruby/lib/jam_ruby/models/recording.rb b/ruby/lib/jam_ruby/models/recording.rb index 1ec43b9aa..0fbf186e8 100644 --- a/ruby/lib/jam_ruby/models/recording.rb +++ b/ruby/lib/jam_ruby/models/recording.rb @@ -701,6 +701,10 @@ module JamRuby self.save(:validate => false) end + def add_video_data(data) + Recording.where(id: self.id).update_all(external_video_id: data[:video_id]) + end + def add_timeline(timeline) global = timeline["global"] raise JamArgumentError, "global must be specified" unless global diff --git a/ruby/lib/jam_ruby/models/user_authorization.rb b/ruby/lib/jam_ruby/models/user_authorization.rb index e83bb8db4..f4c1523eb 100644 --- a/ruby/lib/jam_ruby/models/user_authorization.rb +++ b/ruby/lib/jam_ruby/models/user_authorization.rb @@ -1,7 +1,7 @@ module JamRuby class UserAuthorization < ActiveRecord::Base - attr_accessible :provider, :uid, :token, :token_expiration, :secret, :user + attr_accessible :provider, :uid, :token, :token_expiration, :secret, :user, :refresh_token self.table_name = "user_authorizations" @@ -12,6 +12,36 @@ module JamRuby validates_uniqueness_of :uid, scope: :provider # token, secret, token_expiration can be missing + def self.refreshing_google_auth(user) + auth = self.where(:user_id => user.id) + .where(:provider => 'google_login') + .limit(1).first + + # if we have an auth that will expire in less than 10 minutes + if auth && auth.refresh_token && auth.token_expiration < Time.now - 60 * 10 + + begin + oauth_client = OAuth2::Client.new( + Rails.application.config.google_client_id, Rails.application.config.google_secret, + :site => "https://accounts.google.com", + :token_url => "/o/oauth2/token", + :authorize_url => "/o/oauth2/auth") + access_token = OAuth2::AccessToken.from_hash(oauth_client, {:refresh_token => auth.refresh_token}) + access_token = access_token.refresh! + + auth.token = access_token.token + auth.token_expiration = Time.now + access_token.expires_in + auth.save + return auth + rescue Exception => e + # couldn't refresh; probably the user has revoked the app's rights + return nil + end + else + auth + end + end + def self.google_auth(user) self .where(:user_id => user.id) diff --git a/ruby/spec/support/utilities.rb b/ruby/spec/support/utilities.rb index d909b57d2..e33df4093 100644 --- a/ruby/spec/support/utilities.rb +++ b/ruby/spec/support/utilities.rb @@ -7,6 +7,10 @@ def app_config 'http://localhost:3333' end + def email_social_alias + 'social@jamkazam.com' + end + def email_alerts_alias 'alerts@jamkazam.com' end diff --git a/web/Gemfile b/web/Gemfile index 49217de8a..dbf0f8454 100644 --- a/web/Gemfile +++ b/web/Gemfile @@ -41,12 +41,12 @@ gem 'eventmachine', '1.0.4' gem 'faraday', '~>0.9.0' gem 'amqp', '0.9.8' gem 'logging-rails', :require => 'logging/rails' -gem 'omniauth', '1.1.1' -gem 'omniauth-facebook', '1.4.1' +gem 'omniauth' +gem 'omniauth-facebook' gem 'omniauth-twitter' -gem 'omniauth-google-oauth2', '0.2.1' -gem 'google-api-client', '0.7.1' -gem 'google-api-omniauth', '0.1.1' +gem 'omniauth-google-oauth2' +gem 'google-api-client' #, '0.7.1' +#gem 'google-api-omniauth' #, '0.1.1' gem 'signet', '0.5.0' gem 'twitter' gem 'fb_graph', '2.5.9' diff --git a/web/app/assets/javascripts/dialog/deleteVideoConfirmDialog.js b/web/app/assets/javascripts/dialog/deleteVideoConfirmDialog.js new file mode 100644 index 000000000..8b6c06811 --- /dev/null +++ b/web/app/assets/javascripts/dialog/deleteVideoConfirmDialog.js @@ -0,0 +1,69 @@ +(function (context, $) { + + "use strict"; + context.JK = context.JK || {}; + context.JK.DeleteVideoConfirmDialog = function (app) { + var logger = context.JK.logger; + var rest = context.JK.Rest(); + var recordingId = null; + var $dialog = null; + var $deleteFromDiskChkBox = null; + var $deleteBtn = null; + var deleting = false; + function resetForm() { + + } + + function beforeShow(args) { + + recordingId = args.d1; + + if(!recordingId) throw "recordingId must be specified"; + + $dialog.data('result', null); + deleting = false; + + } + + function afterHide() { + + } + + function attemptDelete() { + if(deleting) return; + + deleting = true; + + rest.deleteRecordingVideoData(recordingId) + .done(function(){ + $dialog.data('result', true); + app.layout.closeDialog('delete-video-confirm-dialog'); + }) + .fail(app.ajaxError) + } + + function events() { + $deleteBtn.click(attemptDelete); + } + + + function initialize() { + var dialogBindings = { + 'beforeShow': beforeShow, + 'afterHide': afterHide + }; + + app.bindDialog('delete-video-confirm-dialog', dialogBindings); + + $dialog = $('#deleteVideoConfirmDialog'); + $deleteFromDiskChkBox = $dialog.find('.delete-from-disk'); + $deleteBtn = $dialog.find('.delete-btn'); + + events(); + + context.JK.checkbox($deleteFromDiskChkBox); + }; + + this.initialize = initialize; + } +})(window, jQuery); \ No newline at end of file diff --git a/web/app/assets/javascripts/dialog/editRecordingDialog.js b/web/app/assets/javascripts/dialog/editRecordingDialog.js index 9aac9d33a..409318c0a 100644 --- a/web/app/assets/javascripts/dialog/editRecordingDialog.js +++ b/web/app/assets/javascripts/dialog/editRecordingDialog.js @@ -14,7 +14,7 @@ var $isPublic = null; var $saveBtn = null; var $deleteBtn = null; - + var $videoField = null; var updating = false; var deleting = false; diff --git a/web/app/assets/javascripts/dialog/recordingFinishedDialog.js b/web/app/assets/javascripts/dialog/recordingFinishedDialog.js index c9440dd80..d350841e8 100644 --- a/web/app/assets/javascripts/dialog/recordingFinishedDialog.js +++ b/web/app/assets/javascripts/dialog/recordingFinishedDialog.js @@ -8,6 +8,8 @@ var playbackControls = null; var recording = null; // deferred object var $dialog = null; + var $saveVideoCheckbox = null + var $uploadToYoutube = null function resetForm() { // remove all display errors @@ -113,9 +115,15 @@ if(recording && recording.video) { var name = $('#recording-finished-dialog form input[name=name]').val(); name = name.replace(/[^A-Za-z0-9\-\ ]/g, ''); - var keep = $('#recording-finished-dialog form input[name=save_video]').is(':checked') - logger.debug("VideoDecision rid:" + recording.id + ", name=" + name + ", keep=" + keep) - context.jamClient.VideoDecision(recording.id, name, keep) + + + var saveToDisk = $('#recording-finished-dialog form input[name=save_video]').is(':checked') + var keepResult = $dialog.data('result'); + keepResult = keepResult && keepResult.keep + + logger.debug("VideoDecision rid:" + recording.id + ", name=" + name + ", keepResult=" + keepResult + ", saveToDisk=" + saveToDisk); + + context.jamClient.VideoDecision(recording.id, name, keepResult && saveToDisk) } recording = null; @@ -156,6 +164,7 @@ window._oauth_callback = function() { window._oauth_win.close() + logger.debug("closing window") setGoogleAuthState() } return false; @@ -167,6 +176,8 @@ var upload_to_youtube = $('#recording-finished-dialog form input[name=upload_to_youtube]').is(':checked') + upload_to_youtube = false // don't prevent user from getting through dialog because popup now handles auth + if (upload_to_youtube) { $.ajax({ type: "GET", @@ -197,6 +208,7 @@ var save_video = $('#recording-finished-dialog form input[name=save_video]').is(':checked') var upload_to_youtube = $('#recording-finished-dialog form input[name=upload_to_youtube]').is(':checked') + var recording_id = recording.id rest.claimRecording({ id: recording.id, name: name, @@ -210,6 +222,11 @@ $dialog.data('result', {keep:true}); app.layout.closeDialog('recordingFinished'); context.JK.GA.trackMakeRecording(); + if(save_video && upload_to_youtube) { + // you have to have elected to save video to have upload to youtube have + context.VideoUploaderActions.showUploader(recording_id); + } + }) .fail(function (jqXHR) { if (jqXHR.status == 422) { @@ -296,9 +313,9 @@ // Check for google authorization using AJAX and show/hide the // google login button / "signed in" label as appropriate: - $(window).on('focus', function() { + /**$(window).on('focus', function() { setGoogleAuthState(); - }); + }); */ } function setGoogleAuthState() { @@ -333,10 +350,24 @@ } function initializeButtons() { + $saveVideoCheckbox = $('#recording-finished-dialog input[name="save_video"]') + $uploadToYoutube = $('#recording-finished-dialog input[name="upload_to_youtube"]') var isPublic = $('#recording-finished-dialog input[name="is_public"]'); context.JK.checkbox(isPublic); - context.JK.checkbox($('#recording-finished-dialog input[name="save_video"]')); - context.JK.checkbox($('#recording-finished-dialog input[name="upload_to_youtube"]')); + context.JK.checkbox($saveVideoCheckbox); + context.JK.checkbox($uploadToYoutube); + + $saveVideoCheckbox.on('ifChanged', function() { + var saveVideoToDisk = $saveVideoCheckbox.is(':checked') + + if(saveVideoToDisk) { + $uploadToYoutube.iCheck('enable') + } + else { + $uploadToYoutube.iCheck('disable') + } + + }) } function initialize() { diff --git a/web/app/assets/javascripts/feedHelper.js b/web/app/assets/javascripts/feedHelper.js index cdf32c7f9..d7ce6765f 100644 --- a/web/app/assets/javascripts/feedHelper.js +++ b/web/app/assets/javascripts/feedHelper.js @@ -471,6 +471,43 @@ $controls.data('server-info', feed.mix) // for recordingUtils helper methods $controls.data('view-context', 'feed') + // tack on video if available + if(feed.external_video_id) { + + var $videoWrapper = $feedItem.find('.video-wrapper') + var $videoContainer = $feedItem.find('.video-container') + if(gon.isNativeClient) { + var $embed = $('' + + '' + + '') + $videoContainer.append($embed).addClass('no-embed') + $videoWrapper.removeClass('hidden') + $embed.click(function() { + context.JK.popExternalLink($(this).attr('href')) + return false; + }) + } + else { + var $embed = $('