diff --git a/app/assets/javascripts/osem-schedule.js b/app/assets/javascripts/osem-schedule.js index aeb76ae3..ac1099d1 100644 --- a/app/assets/javascripts/osem-schedule.js +++ b/app/assets/javascripts/osem-schedule.js @@ -115,6 +115,9 @@ $(document).ready( function() { }); function eventClicked(e, element){ + if (e.target.href) { + return; + } var url = $(element).data('url'); if(e.ctrlKey) window.open(url,'_blank'); diff --git a/app/controllers/admin/rooms_controller.rb b/app/controllers/admin/rooms_controller.rb index c4fac65d..58c2fd83 100644 --- a/app/controllers/admin/rooms_controller.rb +++ b/app/controllers/admin/rooms_controller.rb @@ -48,7 +48,7 @@ module Admin private def room_params - params.require(:room).permit(:name, :size) + params.require(:room).permit(:name, :size, :url) end end end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index c15681aa..31529b62 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -8,6 +8,7 @@ class ApplicationController < ActionController::Base before_action :store_location # Ensure every controller authorizes resource or skips authorization (skip_authorization_check) check_authorization unless: :devise_controller? + skip_authorization_check if: def store_location # store last url - this is needed for post-login redirect to whatever the user last visited. @@ -65,4 +66,9 @@ class ApplicationController < ActionController::Base def not_found raise ActionController::RoutingError.new('Not Found') end + + skip_authorization_check only: :apple_pay + def apple_pay + render plain: ENV['OSEM_APPLE_PAY_ID'] + end end diff --git a/app/helpers/conference_helper.rb b/app/helpers/conference_helper.rb index a48bed54..bd04898c 100644 --- a/app/helpers/conference_helper.rb +++ b/app/helpers/conference_helper.rb @@ -21,4 +21,9 @@ module ConferenceHelper '%20Sponsorship' ].join end + + def short_ticket_description(ticket) + return unless ticket.description + markdown(ticket.description&.split("\n").first&.strip) + end end diff --git a/app/models/commercial.rb b/app/models/commercial.rb index 5acda134..51f8b7f5 100644 --- a/app/models/commercial.rb +++ b/app/models/commercial.rb @@ -18,10 +18,16 @@ class Commercial < ApplicationRecord resource = OEmbed::Providers.get(url, maxwidth: 560, maxheight: 315) { html: resource.html.html_safe } rescue StandardError => exception - { error: exception.message } + { html: iframe_fallback(url) } + # { error: exception.message } end end + def self.iframe_fallback(url) + #
Open in a new tab + "".html_safe + end + def self.read_file(file) errors = {} errors[:no_event] = [] @@ -67,11 +73,10 @@ class Commercial < ApplicationRecord OEmbed::Providers::Instagram, speakerdeck ) - - OEmbed::Providers.register_fallback( - OEmbed::ProviderDiscovery, - OEmbed::Providers::Noembed - ) + # OEmbed::Providers.register_fallback( + # OEmbed::ProviderDiscovery, + # OEmbed::Providers::Noembed + # ) end def conference_id diff --git a/app/views/admin/registrations/index.csv.haml b/app/views/admin/registrations/index.csv.haml index 76f01211..1929abb1 100644 --- a/app/views/admin/registrations/index.csv.haml +++ b/app/views/admin/registrations/index.csv.haml @@ -2,15 +2,11 @@ 'Name', 'Nickname', 'Affilιation', - 'Email', - 'Arrival', - 'Departure'] + 'Email'] = CSV.generate_line headers - @registrations.each do |registration| = CSV.generate_line([registration.attended ? 'X' : '', registration.name, registration.nickname, registration.affiliation, - registration.email, - registration.arrival.to_s, - registration.departure.to_s]) + registration.email]) diff --git a/app/views/admin/rooms/_form.html.haml b/app/views/admin/rooms/_form.html.haml index 90de99e0..951e4094 100644 --- a/app/views/admin/rooms/_form.html.haml +++ b/app/views/admin/rooms/_form.html.haml @@ -11,5 +11,8 @@ = semantic_form_for(@room, url: (@room.new_record? ? admin_conference_venue_rooms_path : admin_conference_venue_room_path(@conference.short_title, @room))) do |f| = f.input :name, input_html: { autofocus: true } = f.input :size, label: 'Capacity', input_html: {size: 5} + = f.input :url, label: 'URL' + %p.small + The URL is only visible to registered attendees. %p.text-right = f.action :submit, as: :button, button_html: { class: 'btn btn-primary' } diff --git a/app/views/admin/rooms/index.html.haml b/app/views/admin/rooms/index.html.haml index 2d1545f6..fd548d59 100644 --- a/app/views/admin/rooms/index.html.haml +++ b/app/views/admin/rooms/index.html.haml @@ -12,6 +12,7 @@ %thead %th Name %th Capacity + %th URL %th Actions %tbody - @rooms.each_with_index do |room, index| @@ -21,11 +22,13 @@ %td = room.size %td - = link_to 'Edit', edit_admin_conference_venue_room_path(@conference.short_title, room.id), - method: :get, class: 'btn btn-primary' - = link_to 'Delete', admin_conference_venue_room_path(@conference.short_title, room.id), - method: :delete, class: 'btn btn-danger', - data: { confirm: "Do you really want to delete #{room.name}? Attention: This room will be removed from all Events that have it set"} + = room.url + %td + = link_to 'Edit', edit_admin_conference_venue_room_path(@conference.short_title, room.id), class: 'btn btn-primary' + = link_to('Delete', + admin_conference_venue_room_path(@conference.short_title, room.id), + method: :delete, class: 'btn btn-danger', + data: { confirm: "Do you really want to delete #{room.name}? Attention: This room will be removed from all Events that have it set"}) .row .col-md-12.text-right = link_to 'Add Room', new_admin_conference_venue_room_path(@conference.short_title), class: 'btn btn-primary' diff --git a/app/views/conferences/_program.haml b/app/views/conferences/_program.haml index 2998c2f0..dc11119c 100644 --- a/app/views/conferences/_program.haml +++ b/app/views/conferences/_program.haml @@ -1,6 +1,8 @@ = content_for :splash_nav do %li %a.smoothscroll{ href: '#program' } Program + %li + = link_to('Schedule', conference_schedule_path(@conference)) - cache [conference, highlights, tracks, booths, '#splash#program'] do %section#program diff --git a/app/views/conferences/_tickets.haml b/app/views/conferences/_tickets.haml index 8e29558d..65f7e602 100644 --- a/app/views/conferences/_tickets.haml +++ b/app/views/conferences/_tickets.haml @@ -20,7 +20,7 @@ %h3.text-center.word_break = ticket.title .word_break - = markdown(ticket.description.split("\n")&.first.strip) + = short_ticket_description(ticket) %button.btn-block.btn.btn-lg.btn-success %i.fa.fa-ticket.fa-fw{"aria-hidden": true} = humanized_money_with_symbol(ticket.price) diff --git a/app/views/devise/shared/_help.html.haml b/app/views/devise/shared/_help.html.haml index 22a7ce21..99eff9f1 100644 --- a/app/views/devise/shared/_help.html.haml +++ b/app/views/devise/shared/_help.html.haml @@ -1,5 +1,5 @@ %p.text-right %a.small.btn.btn-default.btn-xs{"data-toggle" => "collapse", "data-target" => "#devise-help"} - Need Help? + Can't login? #devise-help.collapse = render 'devise/shared/links' diff --git a/app/views/devise/shared/_openid_links.html.haml b/app/views/devise/shared/_openid_links.html.haml index 31b4a176..01f07d4a 100644 --- a/app/views/devise/shared/_openid_links.html.haml +++ b/app/views/devise/shared/_openid_links.html.haml @@ -15,3 +15,9 @@ %span Snap %em> ! +%br +.text-center + %em If you are not currently logged into Snap! or the Snap! Forums, you will need to log in to + Snap!Con twice when using your Snap! account. We're working on fixing this. Thanks! + +%br diff --git a/app/views/devise/shared/_sign_up_form_embedded.html.haml b/app/views/devise/shared/_sign_up_form_embedded.html.haml index fa4bb502..94e249c4 100644 --- a/app/views/devise/shared/_sign_up_form_embedded.html.haml +++ b/app/views/devise/shared/_sign_up_form_embedded.html.haml @@ -2,7 +2,10 @@ %p %strong Create an account directly for Snap!Con, or sign in using Google. %p - Snap!Con uses a different account system, but please use the same username or email address if possible. (We're working on improving this!) + You may sign in via Snap!, but the first time you try, you + %em might not + be redirected back to Snap!Con. If that happens, try a second time and the login will work. + We're trying to fix this issue. Thanks! = semantic_fields_for @user do |u| = u.input :username, input_html: { required: 'required', autocomplete: 'off' } = u.input :email, input_html: { required: 'required', autocomplete: 'off' } diff --git a/app/views/layouts/_navigation.html.haml b/app/views/layouts/_navigation.html.haml index ddc8634a..794caa96 100644 --- a/app/views/layouts/_navigation.html.haml +++ b/app/views/layouts/_navigation.html.haml @@ -19,6 +19,10 @@ - if content_for :splash_nav %ul.nav.navbar-nav#splash-nav = content_for :splash_nav + %li + = link_to 'https://snap.berkeley.edu', target: '_blank' do + Snap + %em ! -if user_signed_in? .btn-group.pull-right %ul.nav.navbar-nav.navbar-right diff --git a/app/views/proposals/show.html.haml b/app/views/proposals/show.html.haml index a7a155bb..217a76b3 100644 --- a/app/views/proposals/show.html.haml +++ b/app/views/proposals/show.html.haml @@ -8,21 +8,25 @@ %meta{ property: "og:image:secure_url", content: @speakers_ordered.first.gravatar_url } .container - .row - .col-md-12.page-header + .row.page-header + .col-md-10 %h2 = @event.title - if @event.subtitle %br %small = @event.subtitle - .btn-group.pull-right - - if can? :update, @event - = link_to 'Registrations', registrations_conference_program_proposal_path(@conference.short_title, @event), class: 'btn btn-mini btn-success' - - if can? :edit, @event - = link_to "Edit", edit_conference_program_proposal_path(@conference.short_title, @event), class: 'btn btn-mini btn-primary' - - if can? :schedule, @conference - = link_to "Schedule", conference_schedule_path(@conference.short_title), class: 'btn btn-success' + - if @event.room&.url && @conference.user_registered?(current_user) + %h3 + = link_to('Join Event', @event.room.url, target: '_blank') + .col-md-2 + %p{style: "margin-top: 20px"} + - if can?(:update, @event) && @event.require_registration? + = link_to 'Registrations', registrations_conference_program_proposal_path(@conference.short_title, @event), class: 'btn btn-mini btn-success' + - if can?(:edit, @event) + = link_to "Edit", edit_conference_program_proposal_path(@conference.short_title, @event), class: 'btn btn-mini btn-primary' + - if can? :schedule, @conference + = link_to "Schedule", conference_schedule_path(@conference.short_title), class: 'btn btn-success' .row .col-md-3 @@ -58,7 +62,7 @@ - if @event.commercials.empty? %h5.text-warning - No video of the event yet, sorry! + No materials for the event yet, sorry! - unless @conference.commercials.empty? Meanwhile... - unless @conference.commercials.empty? diff --git a/app/views/schedules/_event.html.haml b/app/views/schedules/_event.html.haml index 99ced63b..601afdf5 100644 --- a/app/views/schedules/_event.html.haml +++ b/app/views/schedules/_event.html.haml @@ -17,6 +17,9 @@ %h4 - if(event.speakers.any?) presented by #{event.speaker_names} + - if event.room&.url && @conference.user_registered?(current_user) + %p + = link_to('Join Event', event.room.url, target: '_blank') %p = markdown(truncate(event.abstract, length: 400)) = link_to 'more', conference_program_proposal_path(@conference.short_title, event.id) if event.abstract.length > 400 diff --git a/app/views/schedules/show.html.haml b/app/views/schedules/show.html.haml index 355cafad..c1ca83aa 100644 --- a/app/views/schedules/show.html.haml +++ b/app/views/schedules/show.html.haml @@ -1,5 +1,5 @@ .container - = render partial: 'schedule_tabs', locals: { active: 'schedule' } + = render partial: 'schedule_tabs', locals: { active: 'schedule' } #schedule-content %h1.text-center diff --git a/app/views/shared/_media_item.html.haml b/app/views/shared/_media_item.html.haml index 9357c9e2..72d94d5f 100644 --- a/app/views/shared/_media_item.html.haml +++ b/app/views/shared/_media_item.html.haml @@ -1,15 +1,19 @@ -- if commercial.url - = Commercial.render_from_url(commercial.url)[:html] -- else - - if commercial.commercial_type == 'SlideShare' - %iframe{width: '560', height: '315', frameborder: '0', allowfullscreen: 'true', src: "https://www.slideshare.net/slideshow/embed_code/#{commercial.commercial_id}"} - - elsif commercial.commercial_type == 'Flickr' - %iframe{width: '560', height: '315', frameborder: '0', allowfullscreen: 'true', src: "https://flic.kr/p/#{commercial.commercial_id}/player/268a054da2"} - - elsif commercial.commercial_type == 'Vimeo' - %iframe{width: '560', height: '315', frameborder: '0', allowfullscreen: 'true', src: "//player.vimeo.com/video/#{commercial.commercial_id}"} - - elsif commercial.commercial_type == 'Speakerdeck' - %iframe{width: '560', height: '315', frameborder: '0', allowfullscreen: 'true', src: "https://speakerdeck.com/player/#{commercial.commercial_id}?"} - - elsif commercial.commercial_type == 'Instagram' - %iframe{width: '560', height: '315', frameborder: '0', allowfullscreen: 'true', scrolling: 'no', allowtransparency: 'true', src: "//instagram.com/p/#{commercial.commercial_id}/embed/"} +.flexvideo + - if commercial.url + = Commercial.render_from_url(commercial.url)[:html] - else - %iframe{width: '560', height: '315', frameborder: '0', allowfullscreen: 'true', src: "https://www.youtube.com/embed/#{commercial.commercial_id}?rel=0"} + - if commercial.commercial_type == 'SlideShare' + %iframe{width: '560', height: '315', frameborder: '0', allowfullscreen: 'true', src: "https://www.slideshare.net/slideshow/embed_code/#{commercial.commercial_id}"} + - elsif commercial.commercial_type == 'Flickr' + %iframe{width: '560', height: '315', frameborder: '0', allowfullscreen: 'true', src: "https://flic.kr/p/#{commercial.commercial_id}/player/268a054da2"} + - elsif commercial.commercial_type == 'Vimeo' + %iframe{width: '560', height: '315', frameborder: '0', allowfullscreen: 'true', src: "//player.vimeo.com/video/#{commercial.commercial_id}"} + - elsif commercial.commercial_type == 'Speakerdeck' + %iframe{width: '560', height: '315', frameborder: '0', allowfullscreen: 'true', src: "https://speakerdeck.com/player/#{commercial.commercial_id}?"} + - elsif commercial.commercial_type == 'Instagram' + %iframe{width: '560', height: '315', frameborder: '0', allowfullscreen: 'true', scrolling: 'no', allowtransparency: 'true', src: "//instagram.com/p/#{commercial.commercial_id}/embed/"} + - else + %iframe{width: '560', height: '315', frameborder: '0', allowfullscreen: 'true', src: "https://www.youtube.com/embed/#{commercial.commercial_id}?rel=0"} +- if commercial.url + %br + = link_to('Open in a new tab', commercial.url, target: '_blank') diff --git a/app/views/shared/_media_items.html.haml b/app/views/shared/_media_items.html.haml index e4ef3c0d..2801ad79 100644 --- a/app/views/shared/_media_items.html.haml +++ b/app/views/shared/_media_items.html.haml @@ -1,7 +1,6 @@ - unless commercials.empty? - if commercials.length == 1 - .flexvideo - = render partial: 'shared/media_item', locals: { commercial: commercials.first } + = render partial: 'shared/media_item', locals: { commercial: commercials.first } - else %ul.nav.nav-tabs{ 'role'=>'tablist' } - commercials.each.with_index(1) do |commercial, index| @@ -12,9 +11,7 @@ - commercials.each.with_index(1) do |commercial, index| - if index == 1 .tab-pane.active{'id'=>"#{index}"} - .flexvideo - = render partial: 'shared/media_item', locals: { commercial: commercial } + = render partial: 'shared/media_item', locals: { commercial: commercial } - else .tab-pane{'id'=>"#{index}"} - .flexvideo - = render partial: 'shared/media_item', locals: { commercial: commercial } + = render partial: 'shared/media_item', locals: { commercial: commercial } diff --git a/config/database.yml b/config/database.yml index dd8ac693..77437363 100644 --- a/config/database.yml +++ b/config/database.yml @@ -11,14 +11,15 @@ default: &default encoding: <%= encoding %> host: <%= ENV['OSEM_DB_HOST'] || 'database' %> port: <%= ENV['OSEM_DB_PORT'] || '5432' %> - username: <%= ENV['OSEM_DB_USER'] || 'postgres' %> - password: <%= ENV['OSEM_DB_PASSWORD'] || 'mysecretpassword' %> + # username: <%= ENV['OSEM_DB_USER'] || 'postgres' %> + # password: <%= ENV['OSEM_DB_PASSWORD'] || 'mysecretpassword' %> database: <%= ENV['OSEM_DB_NAME'] || 'postgres' %> pool: 5 timeout: 5000 development: <<: *default + host: localhost database: osem_development # Warning: The database defined as "test" will be erased and @@ -26,6 +27,7 @@ development: # Do not set this db to the same as development or production. test: <<: *default + host: localhost database: osem_test production: diff --git a/config/routes.rb b/config/routes.rb index 478e7294..0d6084e6 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -230,4 +230,6 @@ Osem::Application.routes.draw do else root to: 'conferences#index', via: [:get, :options] end + + get '/.well-known/apple-developer-merchantid-domain-association', to: 'application#apple_pay' end diff --git a/db/migrate/20200710215300_add_url_to_rooms.rb b/db/migrate/20200710215300_add_url_to_rooms.rb new file mode 100644 index 00000000..8eefff7b --- /dev/null +++ b/db/migrate/20200710215300_add_url_to_rooms.rb @@ -0,0 +1,5 @@ +class AddUrlToRooms < ActiveRecord::Migration[5.2] + def change + add_column :rooms, :url, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index c16b9f8f..f888a737 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,10 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2020_03_31_214534) do +ActiveRecord::Schema.define(version: 2020_07_10_215300) do + + # These are extensions that must be enabled in order to support this database + enable_extension "plpgsql" create_table "answers", force: :cascade do |t| t.string "title" @@ -403,6 +406,7 @@ ActiveRecord::Schema.define(version: 2020_03_31_214534) do t.string "name", null: false t.integer "size" t.integer "venue_id", null: false + t.string "url" end create_table "schedules", force: :cascade do |t| @@ -638,7 +642,7 @@ ActiveRecord::Schema.define(version: 2020_03_31_214534) do t.text "object_changes" t.datetime "created_at" t.integer "conference_id" - t.integer "organization_id" + t.bigint "organization_id" t.index ["item_type", "item_id"], name: "index_versions_on_item_type_and_item_id" t.index ["organization_id"], name: "index_versions_on_organization_id" end diff --git a/lib/tasks/db.rake b/lib/tasks/db.rake index 39db898f..3c9cded7 100644 --- a/lib/tasks/db.rake +++ b/lib/tasks/db.rake @@ -12,4 +12,25 @@ namespace :db do puts 'Database exists, skipping bootstrap...' end end + + desc "Import a given file into the database" + task :import, [:path] => :environment do |_t, args| + dump_path = args.path + connection_config = ActiveRecord::Base.connection_config + + case connection_config[:adapter] + when "postgresql" + system("PGPASSWORD=#{connection_config[:password]} pg_restore " \ + "--verbose --clean --no-acl --no-owner " \ + "--username=#{connection_config[:username]} " \ + "-d #{connection_config[:database]} #{dump_path}") + when "mysql", "mysql2" + system("mysql -u #{connection_config[:username]} " \ + "-p#{connection_config[:password]} " \ + "#{connection_config[:database]} < #{dump_path}") + else + raise NotImplementedError, "An importer hasn't been implemented for: " \ + "#{connection_config[:adapter]}" + end + end end