commit cc69740245256df61b3f7f29c20b4ca55d6e0cb8 Author: 邱博亞 Date: Wed Aug 14 00:06:11 2024 +0800 First version diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..de5d954 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +.bundle/ +log/*.log +pkg/ +test/dummy/db/*.sqlite3 +test/dummy/db/*.sqlite3-journal +test/dummy/log/*.log +test/dummy/tmp/ +test/dummy/.sass-cache diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..d15019e --- /dev/null +++ b/Gemfile @@ -0,0 +1,14 @@ +source "https://rubygems.org" + +# Declare your gem's dependencies in bulletin.gemspec. +# Bundler will treat runtime dependencies like base dependencies, and +# development dependencies will be added by default to the :development group. +gemspec + +# Declare any dependencies that are still in development here instead of in +# your gemspec. These might include edge Rails or gems from your path or +# Git. Remember to move these dependencies to your gemspec before releasing +# your gem to rubygems.org. + +# To use debugger +# gem 'debugger' diff --git a/MIT-LICENSE b/MIT-LICENSE new file mode 100644 index 0000000..ea966ec --- /dev/null +++ b/MIT-LICENSE @@ -0,0 +1,20 @@ +Copyright 2014 YOURNAME + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.rdoc b/README.rdoc new file mode 100644 index 0000000..f319e8b --- /dev/null +++ b/README.rdoc @@ -0,0 +1,3 @@ += Video Programs + +This project rocks and uses MIT-LICENSE. \ No newline at end of file diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..6098412 --- /dev/null +++ b/Rakefile @@ -0,0 +1,32 @@ +begin + require 'bundler/setup' +rescue LoadError + puts 'You must `gem install bundler` and `bundle install` to run rake tasks' +end + +require 'rdoc/task' + +RDoc::Task.new(:rdoc) do |rdoc| + rdoc.rdoc_dir = 'rdoc' + rdoc.title = 'Video Programs' + rdoc.options << '--line-numbers' + rdoc.rdoc_files.include('README.rdoc') + rdoc.rdoc_files.include('lib/**/*.rb') +end + + + + +Bundler::GemHelper.install_tasks + +require 'rake/testtask' + +Rake::TestTask.new(:test) do |t| + t.libs << 'lib' + t.libs << 'test' + t.pattern = 'test/**/*_test.rb' + t.verbose = false +end + + +task default: :test diff --git a/app/assets/images/video_program/.keep b/app/assets/images/video_program/.keep new file mode 100644 index 0000000..e69de29 diff --git a/app/assets/images/video_program/AAAAAA.png b/app/assets/images/video_program/AAAAAA.png new file mode 100644 index 0000000..772a39b Binary files /dev/null and b/app/assets/images/video_program/AAAAAA.png differ diff --git a/app/assets/images/video_program/default.jpg b/app/assets/images/video_program/default.jpg new file mode 100644 index 0000000..b6b82f0 Binary files /dev/null and b/app/assets/images/video_program/default.jpg differ diff --git a/app/assets/stylesheets/video-program-card.css b/app/assets/stylesheets/video-program-card.css new file mode 100644 index 0000000..c3ed001 --- /dev/null +++ b/app/assets/stylesheets/video-program-card.css @@ -0,0 +1,111 @@ +.video-program .category-title { + width: 100%; +} +.video-program.card-group .card-body img { + object-fit: cover; +} +.video-program.card-group .row { + position: relative; + display: flex; + flex-wrap: wrap; + width: 100%; +} +.video-program.card-group .card-back { + transform: rotateY(180deg) translateX(-100%); + position: absolute; + backface-visibility: hidden; + transition: transform 300ms; + transition-timing-function: linear; + display: block; + width: 100%; + height: 100%; + top: 0; + background: white; + color: black; +} +.video-program.card-group .card.card-flip.h-100:nth-child(4n) { + margin-right: 0em; +} + +.video-program.card-group .card.card-flip.h-100 { + position: relative; + width: 25%; + width: calc( 25% - 0.75em); + background: white; + margin-right: 1em; + margin-bottom: 1em; +} +@media (max-width: 768px){ + .video-program.card-group .card.card-flip.h-100 { + width: 50%; + width: calc( 50% - 0.5em); + } + .video-program.card-group .card.card-flip.h-100:nth-child(2n) { + margin-right: 0em; + } +} +@media (max-width: 575px){ + .video-program.card-group .card.card-flip.h-100 { + width: 100%; + margin-right: 0em; + } +} +.video-program.card-group h3.card-title { + padding: 0.5em; + margin: 0; + font-size: 1.2em; +} +.video-program.card-group .card-front{ + backface-visibility: hidden; + width: 100%; + height: 100%; +} +.video-program.card-group .card-front .card-footer { + position: absolute; + color: #fff; + left: 0; + bottom: 0; + overflow: hidden; + text-overflow: ellipsis; + max-height: 60%; + background: linear-gradient(transparent, rgba(0, 0, 0, .2) 20%, rgba(0, 0, 0, .8) 90%); +} +.video-program.card-group .card.card-flip.h-100:hover .card-back { + transform: rotateY(0deg); +} +.video-program.card-group .card-button-group{ + bottom: 0; + right: 0; + position: absolute; + display: flex; + vertical-align: middle; +} +.video-program.card-group .card-body{ + width: 100%; + position: inherit; + display: flex; + flex-direction: column; + height: 100%; +} +.video-program.card-group .card-button-group a { + color: #fff; + display: block; + background: #6c757d; + padding: 0.5em; + width: 2.3em; + height: 2.3em; + margin-right: 0.1em; + border-radius: 0; +} +.video-program.card-group .card-button-group a:hover { + color: #fff; + background-color: #5a6268; + border-color: #545b62; +} +.video-program.card-group .card-button-group a:focus { + color: #fff; + outline: 0.1em dotted !important; +} +.video-program.card-group .card-button-group span { + line-height: 2; +} \ No newline at end of file diff --git a/app/controllers/admin/video_programs_controller.rb b/app/controllers/admin/video_programs_controller.rb new file mode 100644 index 0000000..a48d6ff --- /dev/null +++ b/app/controllers/admin/video_programs_controller.rb @@ -0,0 +1,106 @@ +# encoding: utf-8 +require 'rubyXL' +class Admin::VideoProgramsController < OrbitAdminController + before_action ->(module_app = @app_title) { set_variables module_app } + before_action :set_video_program, only: [:edit, :destroy] + + def initialize + super + @app_title = "video_program" + end + + def index + VideoProgram.remove_expired_status + @tags = @module_app.tags + @table_fields = [:status, :category, :title, "video_program.start_date", "video_program.end_date", :last_modified] + @current_user = current_user + if params[:sort].blank? + params[:sort] = 'post_date' + params[:order] = 'desc' + end + @categories = @module_app.categories.enabled.authorized(current_user) + @filter_fields = filter_fields(@categories, @tags) + @video_programs = VideoProgram.where(:category_id.ne=>nil) + .order_by(sort) + .with_categories(filters("category")) + .with_tags(filters("tag")) + .with_status(filters("status")) + @video_programs = search_data(@video_programs,[:title]).page(params[:page]).per(10) + + if request.xhr? + render :partial => "index" + end + end + + def new + @tags = @module_app.tags + @statuses = [] + @video_program = VideoProgram.new + end + + def create + bps = video_program_params + video_program = VideoProgram.new(bps) + if !bps['video_program_links_attributes'].nil? + bps['video_program_links_attributes'].each do |idx,link| + bps['video_program_links_attributes'].delete(idx.to_s) if link['url'].blank? + end + end + + video_program.create_user_id = current_user.id + video_program.update_user_id = current_user.id + + video_program.save + redirect_to params['referer_url'] + end + + def edit + if can_edit_or_delete?(@video_program) + @tags = @module_app.tags + @categories = @module_app.categories.enabled.authorized(current_user) + @statuses = [] + else + render_401 + end + end + + def update + uid = params[:id].split('-').last + video_program = VideoProgram.find_by(:uid=>uid) + bps = video_program_params + bps[:tags] = bps[:tags].blank? ? [] : bps[:tags] + + if !bps['video_program_links_attributes'].nil? + bps['video_program_links_attributes'].each do |idx,link| + bps['video_program_links_attributes'].delete(idx.to_s) if link['url'].blank? + end + end + bps[:update_user_id] = current_user.id + video_program.update_attributes!(bps) + now_video_program_page = VideoProgram.where(:title.ne => "") + .order_by(sort).map(&:id).map.with_index.select{|v,i| v==video_program.id}[0][1] rescue nil + now_video_program_page = now_video_program_page.nil? ? 0 : ((now_video_program_page+1).to_f/10).ceil + redirect_to admin_video_programs_path(:page=>now_video_program_page) + end + + def destroy + @video_program.destroy + redirect_to "/admin/video_programs" + end + + # def delete + # if params[:ids] + # VideoProgram.any_in(:uid => params[:ids]).destroy_all + # end + # redirect_to "/admin/video_programs" + # end + + private + def set_video_program + @video_program = VideoProgram.find(params[:id]) + end + + def video_program_params + params.require(:video_program).permit! + end +end diff --git a/app/controllers/video_programs_controller.rb b/app/controllers/video_programs_controller.rb new file mode 100644 index 0000000..b0b442c --- /dev/null +++ b/app/controllers/video_programs_controller.rb @@ -0,0 +1,228 @@ +class VideoProgramsController < ApplicationController + include VideoProgramsHelper + def initialize + super + @app_title = 'video_program' + end + def short_desc(str, len) + if str && str.length > len + str[0...len] + '...' + else + str + end + end + def index + VideoProgram.remove_expired_status + sorted,total_pages = get_sorted_video_programs + #If no data , hide title&table + if sorted.count == 0 + display_class = "hide" + categories = [] + else + grouped_data = sorted.group_by(&:category_id) + category_title_map = Category.where(:id.in=>grouped_data.keys).pluck(:id, "title.#{I18n.locale}").map{|k,v| [k, v.values[0]]}.to_h + categories = grouped_data.map do |category_id, video_programs| + { + "category-title" => category_title_map[category_id], + "video-programs" => video_programs.map do |vp| + statuses = vp.statuses_with_classname.collect do |status| + { + "status" => status["name"], + "status-class" => "status-#{status['classname']}" + } + end + episodes = vp.episodes || 0 + { + "title" => vp.title, + "subtitle" => short_desc(vp.subtitle, 100), + "episodes" => episodes, + "episodes_text" => t("video_program.episodes_text",{:num=> episodes}), + "thumb-src" => (vp.image.thumb.url || "/assets/video_program/default.jpg"), + "link_to_show" => OrbitHelper.url_to_show(vp.to_param), + "statuses" => statuses + } + end + } + end + end + + { + "categories" => categories, + "extras" => { + "program_notes-head" => t('video_program.program_notes'), + "video_notes-head" => t('video_program.video_notes'), + "play-head" => t('video_program.play'), + "view-count-head" => t('video_program.table.view_count'), + "display_class" => display_class + }, + "total_pages" => total_pages + } + end + + def get_file + @url = request.path + begin + if @url.match(/\/\.\./) + render :file => "#{Rails.root}/app/views/errors/404.html", :layout => false, :status => :not_found, :content_type => 'text/html' + return + end + file = VideoProgramFile.find(params[:id]) + if File.basename(file.file.path) != URI.decode(params[:f_name]) + render :file => "#{Rails.root}/app/views/errors/403.html", :layout => false, :status => :not_found, :content_type => 'text/html' + return + end + @url = file.file.url + if file.can_access?(OrbitHelper.current_user) + @path = file.file.path rescue "" + @filename = @path.split("/").last + @ext = @path.split("/").last.to_s.split(".").last + if @ext == "png" || @ext == "jpg" || @ext == "bmp" || @ext == "pdf" + render "archives/download_file.html",:layout=>false + else + if (current_site.accessibility_mode rescue false) + render "archives/redirect_to_file.html",:layout=>false + return + else + send_file(@path) + return + end + end + else + render :file => "#{Rails.root}/app/views/errors/403.html", :layout => false, :status => :not_found, :content_type => 'text/html' + return + end + rescue + render :file => "#{Rails.root}/app/views/errors/404.html", :layout => false, :status => :not_found, :content_type => 'text/html' + return + end + end + + def show_local_video_program(uid) + locale = OrbitHelper.get_site_locale.to_s + video_program = VideoProgram.where(:uid => uid).first + return nil if video_program.nil? + url_to_edit = OrbitHelper.user_can_edit?(video_program) ? "/admin/video_program/#{video_program.id.to_s}/edit" : "" + + return {} if (video_program.category.disable rescue false) + + tags = video_program.tags.map{|tag| { + "tag" => tag.name , + "url" => OrbitHelper.page_for_tag(tag) + } } + files = video_program.video_program_files.to_fronted(locale) + links = video_program.video_program_links.map{|link| { "link_url" => link.url, "link_title" => (link.title.blank? ? link.url : link.title) } } rescue [] + update_user = video_program.update_user.member_profile.name rescue "" + desc = OrbitHelper.get_default_value(video_program.image_description, "VideoProgram image") + + request = OrbitHelper.request + meta_desc = video_program.subtitle.nil? || video_program.subtitle == "" ? short_desc(video_program.video_notes, 200) : video_program.subtitle + OrbitHelper.render_meta_tags([{"property" => "og:title", "content" => video_program.title},{"property" => "og:site_name", "content" => Site.first.title},{"property" => "og:url", "content" => request.original_url.split("?").first},{"property" => "og:description", "content" => meta_desc},{"property" => "og:image", "content" => "#{request.base_url}#{video_program.image.url}"},{"property" => "og:type", "content" => "Article"}]) + + subtitle = nil + image_html = nil + video_image_html = nil + img_description = nil + video_img_description = nil + subtitle = video_program.subtitle + if video_program.display_image && video_program.image.present? + img_description = OrbitHelper.get_default_value(video_program.image_description, video_program.title) + image_html = "\"#{img_description}\"" + end + if video_program.display_video_image && video_program.video_image.present? + video_img_description = OrbitHelper.get_default_value(video_program.video_image_description, video_program.title) + video_image_html = "\"#{video_img_description}\"" + end + if video_program.video_external_link.present? + video_external_link = video_program.video_external_link + video_external_link_class = "" + else + video_external_link = "javascript:;" + video_external_link_class = "disabled" + end + video_program_carousel_images = video_program.video_program_carousel_images.map{|image| {"src"=>image.file.url,"description"=>image.description.to_s,"description_text"=>image.description_text }} + resume_btn_title = t("plugin_control.resume") + pause_btn_title = t("plugin_control.pause") + prev_btn_title = t("plugin_control.prev") + next_btn_title = t("plugin_control.next") + episodes_text = t("video_program.episodes_text",{:num=> video_program.episodes}) + grouped_data = video_program.albums.asc(:order).group_by{|a| a.tag_ids.first} + tag_sort_number_map = {} + tag_title_map = Tag.where(:id.in=>grouped_data.keys).pluck(:id, "name.#{I18n.locale}", :tmp_sort_number).map do |k,v, sort_number| + tag_sort_number_map[k] = sort_number + [k, v.values[0]] + end.to_h + episodes_albums = grouped_data.sort_by{|k, v| tag_sort_number_map[k].to_i}.map.with_index do |(tag_id, albums), i| + tag_name = tag_id ? tag_title_map[tag_id] : nil + images = albums.map do |album| + skip_tag_ids = album.tag_ids + album.album_images.asc(:order).map do |album_image| + { + "img-src" => album_image.file.url, + "img-tags" => album_image.tags.map{|tag| + next if skip_tag_ids.include?(tag.id) + { + "tag" => tag.name, + } + }.compact, + "ep_title" => album_image.title, + "ep_desc" => album_image.description + } + end + end.flatten + { + "images_tag" => tag_name, + "images" => images, + "tab-class" => (i == 0 ? 'active in' : ''), + "tab-index" => i + } + end + data = { + "tags" => tags, + "video_program_files" => files, + "video_program_links" => links, + "episodes_albums" => episodes_albums, + "data" => { + "title-head" => t('video_program.title'), + "program_notes-head" => t('video_program.program_notes'), + "actor_notes-head" => t('video_program.actor_notes'), + "video_notes-head" => t('video_program.video_notes'), + "carousel_image-head" => t('video_program.carousel_image'), + "episodes_albums-head" => t('video_program.episodes_albums'), + "play-head" => t('video_program.play'), + "program_notes" => video_program.program_notes, + "program_notes_class" => (video_program.program_notes.present? ? "" : "hide"), + "actor_notes" => video_program.actor_notes, + "actor_notes_class" => (video_program.actor_notes.present? ? "" : "hide"), + "video_notes" => video_program.video_notes, + "episodes_albums_class" => (episodes_albums.present? ? "" : "hide"), + "title" => video_program.title, + "subtitle" => subtitle, + "image_html" => image_html, + "video_image_html" => video_image_html, + "img_description" => img_description, + "video_img_description" => video_img_description, + "alt_title" => desc, + "resume_btn_title" => resume_btn_title, + "pause_btn_title" => pause_btn_title, + "prev_btn_title" => prev_btn_title, + "next_btn_title" => next_btn_title, + "carousel_display_style" => (video_program_carousel_images.count == 0 ? 'display: none;' : video_program.carousel_image_width ? "width: #{video_program.carousel_image_width};margin: auto;" : nil), + "carousel_count" => video_program_carousel_images.count, + "video_external_link" => video_external_link, + "video_external_link_class" => video_external_link_class, + "episodes_text" => episodes_text, + "carousel_image_class" => (video_program_carousel_images.present? ? "" : "hide") + }, + "impressionist" => video_program, + "url_to_edit"=>url_to_edit + } + data['data']['video_program_carousel_images'] = (video_program_carousel_images.present? ? render_ad_banner(video_program_carousel_images,data['data']) : nil) + data + end + + def show + params = OrbitHelper.params + uid = params[:uid].to_s + show_local_video_program(uid) + end +end diff --git a/app/helpers/admin/video_programs_helper.rb b/app/helpers/admin/video_programs_helper.rb new file mode 100644 index 0000000..5d815b9 --- /dev/null +++ b/app/helpers/admin/video_programs_helper.rb @@ -0,0 +1,19 @@ +module Admin::VideoProgramsHelper + def cal_url_to_show(module_app, model) + pages = Page.where(:module=>module_app.key).order_by(id: :asc) + if model.respond_to?(:category_id) && model.category_id + pages = pages.any_of({:categories.in => ['all', model.category_id.to_s]}, {:categories=> {'$size'=> 0}}) + end + puts "pages = #{pages}" + + page_data_list = pages.pluck(:url, :categories).sort_by{|page_data| + page_data[1].length == 1 && page_data[1] != 'all' ? 0 : 1 + } + + if page_data_list + show_page_url = page_data_list[0][0] + return "/#{I18n.locale}#{show_page_url}/#{model.to_param}" + end + return '#' + end +end \ No newline at end of file diff --git a/app/helpers/video_programs_helper.rb b/app/helpers/video_programs_helper.rb new file mode 100644 index 0000000..fb1f2e5 --- /dev/null +++ b/app/helpers/video_programs_helper.rb @@ -0,0 +1,256 @@ +module VideoProgramsHelper + def render_ad_banner(event_carousel_images,data) + ("
+
+
" + + event_carousel_images.collect do |e| + "
+ \"#{e['description_text']}\" +
+

#{e['description']}

+
+
+
" + end.join+ + "
+
+
    + + +
+
+
+

1/#{data['carousel_count']}

+
    " + + event_carousel_images.collect do |e| + "
  • +
    + \"#{e['description_text']}\" +
    +
  • " + end.join + + "
+
    + + +
+
+
").html_safe + end + def get_feed_annc(type,site_source,locale,categories=nil) + ma_key = 'video_programs' + if categories.nil? + if type == "index" + categories = Array(OrbitHelper.page_categories) + elsif type == "widget" + categories = Array(OrbitHelper.widget_categories) + else + categories = [] + end + end + categories = ["all"] if categories.length==0 + if categories.include?("all") + feeds = SiteFeedAnnc.where(:channel_key => ma_key) + else + feeds = SiteFeedAnnc.where(:channel_key => ma_key, :merge_with_category.in => categories) + end + if feeds.count > 0 + temp_ids = [] + data = feeds.collect do |feed| + feed.all_contents_for_feed(site_source,locale,type=='widget') + end.flatten.compact + else + data = [] + end + data + end + def get_feed_video_programs(type,site_source=nil,categories=nil,max_len=nil) + locale = OrbitHelper.get_site_locale.to_s + if !(defined? SiteFeedAnnc).nil? + fans = get_feed_annc(type,site_source,locale,categories) + else + feed_anns = OrbitHelper.get_feed_for_module(type) + fans = [] + feed_anns.each do |fa| + next if !site_source.nil? && site_source != fa["source-site-title"] + status = { + "status" => "#{fa["source-site-title"]}", + "status-class" => "status-source" + } + + files = fa["event_news_files"].collect{|bf| { "file_url" => bf["url"], "file_title" => (fa["title_translations"][locale].blank? ? File.basename(fa["url"]) : fa["title_translations"][locale] rescue '') }} rescue [] + links = fa["event_news_links"].map{|link| { "link_url" => link["url"], "link_title" => (link["title_translations"][locale].blank? ? link["url"] : link["title_translations"][locale]) } } rescue [] + event_time_formated = a.event_time_formated + s = DateTime.parse(fa["event_date"]) rescue nil + e = DateTime.parse(fa["event_end_date"]) rescue nil + date_parse_format = fa["all_day"] ? '%Y-%m-%d' : '%Y-%m-%d %H:%M' + if s.blank? && e.blank? + event_time_formated = "" + elsif s.blank? + event_time_formated = s.strftime(date_parse_format) + elsif e.blank? + event_time_formated = "~ " + e.strftime(date_parse_format) + else + if s.to_date == e.to_date + date_str = s.strftime('%Y-%m-%d') + s_time = s.strftime('%H:%M') + e_time = e.strftime('%H:%M') + event_time_formated = "#{date_str} #{s_time} ~ #{e_time}" + else + event_time_formated = s.strftime(date_parse_format) + " ~ " + e.strftime(date_parse_format) + end + end + x = { + "event_news_links" => links, + "event_news_files" => files, + "event_carousel_images" => fa["event_carousel_images"].to_a, + "title" => fa["title_translations"][locale], + "speaker-css" => (fa["speaker_translations"][locale].blank? ? "display: none;" : ""), + "host-css" => (fa["host_translations"][locale].blank? ? "display: none;" : ""), + "place-css" => (fa["place_translations"][locale].blank? ? "display: none;" : ""), + "event-time-css" => (event_time_formated.blank? ? "display: none;" : ""), + "notes-css" => (fa["notes_translations"][locale].blank? ? "display: none;" : ""), + "event-time-formated" => event_time_formated, + "speaker" => (fa["speaker_translations"][locale].to_s rescue ""), + "place" => (fa["place_translations"][locale].to_s rescue ""), + "host" => (fa["host_translations"][locale].to_s rescue ""), + "notes" => (fa["notes_translations"][locale].to_s rescue ""), + "subtitle" => fa["subtitle_translations"][locale], + "statuses" => [status], + "category" => fa["category"], + "postdate" => (DateTime.parse(fa["event_date"]) rescue DateTime.now), + "event_date" => (DateTime.parse(fa["event_date"]) rescue DateTime.now), + "author" => fa["author"], + "source-site" => "#{fa["source-site-title"]}", + "source-site-title" => fa["source-site-title"], + "source-site-link" => fa["source-site"], + "link_to_show" => OrbitHelper.url_to_show(fa["params"]), + "target" => "_self", + "img_src" => fa["image"]["thumb"] || "/assets/video_programs-default.jpg", + "img_description" => fa["image_description_translations"][locale], + "more" => t("video_programs.more"), + "view_count" => "" + } + if (!x["title"].empty? rescue false) + fans << x + end + end + end + fans + end + def filter_by_keywords(sorted,keywords,stime,etime) + kflag = keywords.blank? + sflag = stime.blank? + eflag = etime.blank? + stime = stime.to_s.split('/') + stime = Time.zone.local(*stime) rescue nil + etime = etime.to_s.split('/') + etime = Time.zone.local(*etime) rescue nil + if !kflag || !sflag || !eflag + sorted.select{|anns| + if kflag + flag = true + else + if anns["source-site"].present? + title = Nokogiri::HTML(anns["title"].to_s).text + else + title = Nokogiri::HTML(anns.title.to_s).text + end + flag = title.include?(keywords.to_s) + end + flag + } + else + sorted + end + end + def get_sorted_video_programs(data_count=nil) + params = OrbitHelper.params + locale = OrbitHelper.get_site_locale.to_s + page_number = OrbitHelper.page_number.to_i + page_number = 1 if page_number == 0 + page_data_count = data_count || OrbitHelper.page_data_count.to_i + feeds_anns = [] + page = OrbitHelper.page rescue nil + page = Page.where(url: params['url']).first if page.nil? + if @type == "show_widget" + tags = @tags + categories = @categories + else + tags = page.tags + tags = params[:tags] if params[:tags].present? + categories = params['category']=='all' ? (page.categories || []) : (Array(params['category']) rescue (page.categories || [])) + if params['category'].present? && tags.blank? + tags = ["all"] + end + end + if params["source"].blank? + if @type == "show_widget" + if params[:uids].blank? + video_programs = VideoProgram.where(:title.nin => ["",nil],:is_preview.in=>[false,nil]) + .can_display_and_sorted + .filter_by_categories(categories,false).filter_by_tags(tags).to_a + else + member_prfile = MemberProfile.any_in(:uid=>params[:uids]) + user_ids = member_prfile.map{|m| m.user.id rescue nil}.select{|id| !id.nil?} + video_programs = VideoProgram.where(:title.nin => ["",nil],:is_preview.in=>[false,nil],:create_user_id.in=>user_ids) + .can_display_and_sorted + .filter_by_categories(categories,false).filter_by_tags(tags).to_a + end + else + video_programs = VideoProgram.where(:title.nin => ["",nil],:is_preview.in=>[false,nil]) + .can_display_and_sorted + .filter_by_categories(categories,false).filter_by_tags(tags).to_a + end + if false #!(defined? SiteFeed).nil? + if @type != "show_widget" + feeds_anns = get_feed_video_programs("index",nil,nil,page_number*page_data_count) + else + feeds_anns = [] + end + end + else + video_programs = [] + if false # @type != "show_widget" + feeds_anns = get_feed_video_programs("index",params["source"],nil,page_number*page_data_count) + else + feeds_anns = [] + end + end + if feeds_anns.present? + if video_programs.count != 0 + top_anns = video_programs.select{|v| v.is_top} + feeds_anns.select{|v| v['is_top']} + rest_all_anns = feeds_anns.select{|v| v['is_top'] != true} + video_programs.select{|v| !v.is_top} + rest_anns = rest_all_anns.sort_by { |a| tmp=a["postdate"].blank?;[tmp ? 0 : 1, tmp ? nil : a["postdate"].to_time] }.reverse + all_sorted = top_anns.sort_by { |a| tmp=a["postdate"].blank?;[tmp ? 0 : 1, tmp ? nil : a["postdate"].to_time] }.reverse + rest_anns + else + all_sorted = feeds_anns.select{|v| v['is_top']}.sort_by { |a| tmp=a["postdate"].blank?;[tmp ? 0 : 1, tmp ? nil : a["postdate"].to_time] }.reverse + feeds_anns.select{|v| v['is_top'] != true}.sort_by { |a| tmp=a["postdate"].blank?;[tmp ? 0 : 1, tmp ? nil : a["postdate"].to_time] }.reverse + end + all_filter = filter_by_keywords(all_sorted,params[:keywords],params[:stime],params[:etime]) + else + all_filter = filter_by_keywords(video_programs,params[:keywords],params[:stime],params[:etime]) + end + if page_data_count != 0 + sorted = all_filter[(page_number-1)*page_data_count...page_number*page_data_count] + else + sorted = all_filter + end + annc_count = all_filter.count + total_pages = page_data_count == 0 ? 1 : (annc_count.to_f / page_data_count).ceil + [sorted,total_pages] + end +end \ No newline at end of file diff --git a/app/models/.keep b/app/models/.keep new file mode 100644 index 0000000..e69de29 diff --git a/app/models/video_program.rb b/app/models/video_program.rb new file mode 100644 index 0000000..8b86c19 --- /dev/null +++ b/app/models/video_program.rb @@ -0,0 +1,80 @@ +class VideoProgram + include Mongoid::Document + include Mongoid::Timestamps + + include OrbitModel::Status + include OrbitModel::Impression + # encoding: utf-8 + include OrbitTag::Taggable + include OrbitCategory::Categorizable + include Slug + + field :custom_carousel_image_width, type: String, default: "" + + field :display_video_image, :type => Boolean, :default => false + mount_uploader :video_image, ImageUploader + field :video_image_description, localize: true + + field :display_image, :type => Boolean, :default => false + mount_uploader :image, ImageUploader + field :image_description, localize: true + + field :title, as: :slug_title, type: String, localize: true + field :subtitle, localize: true + + field :program_notes, type: String, localize: true + field :actor_notes, type: String, localize: true + field :video_notes, type: String, localize: true + + field :video_external_link, type: String + + field :episodes, type: String + + field :create_user_id + field :update_user_id + + field :postdate , :type => DateTime, :default => Time.now + field :deadline , :type => DateTime + + + has_many :video_program_links, :autosave => true, :dependent => :destroy + has_many :video_program_files, :autosave => true, :dependent => :destroy + has_many :video_program_carousel_images, :autosave => true, :dependent => :destroy + accepts_nested_attributes_for :video_program_files, :allow_destroy => true + accepts_nested_attributes_for :video_program_links, :allow_destroy => true + accepts_nested_attributes_for :video_program_carousel_images, :allow_destroy => true + + has_and_belongs_to_many :albums + accepts_nested_attributes_for :albums, :allow_destroy => true + + scope :open_in_future, ->{where(:is_hidden.ne=>true,:postdate.gt=>Time.now).order(postdate: :asc)} + scope :can_display_and_sorted, ->{where(:is_hidden.ne=>true).valid_time_range.order(postdate: :desc)} + scope :can_display_and_sorted_according_today, ->{where(:is_hidden.ne=>true).order(postdate: :asc).valid_time_range.where(:postdate.gte => Date.today.to_time)} + scope :valid_time_range, ->{and_any_of([{"postdate"=>{"$lte"=> Time.now}, "deadline"=>{"$gte"=> Time.now}}, {"postdate"=>{"$lte"=> Time.now}, "deadline"=>nil}]).order((@manually_sort ? {is_top: :desc,postdate: :desc,id: :desc} : {is_top: :desc,postdate: :desc,id: :desc}))} + scope :is_approved_and_show, ->{where(:approved => true,:is_hidden.ne=>true)} + scope :filter_cats_and_tags, ->(cats,tags) {filter_by_widget_categories(cats,false).filter_by_tags(tags)} + before_save do + if @is_hidden_changed.nil? || @is_hidden_changed != true + @is_hidden_changed = self.is_hidden_changed? + end + end + index({postdate: 1}, { unique: false, background: true }) + index({is_top: -1, postdate: -1, _id: -1}, { unique: false, background: true }) + index({is_hidden: 1, is_top: -1, postdate: -1, _id: -1, deadline: -1}, { unique: false, background: true }) + + def update_user + User.find(update_user_id) rescue nil + end + + def update_user=(user) + self.update_user_id = user.id + end + + def expired? + (self.deadline < Time.now) rescue false + end + + def carousel_image_width + (self.custom_carousel_image_width.blank? ? nil : self.custom_carousel_image_width) + end +end diff --git a/app/models/video_program_carousel_image.rb b/app/models/video_program_carousel_image.rb new file mode 100644 index 0000000..2d8e2de --- /dev/null +++ b/app/models/video_program_carousel_image.rb @@ -0,0 +1,15 @@ +# encoding: utf-8 +class VideoProgramCarouselImage + + include Mongoid::Document + include Mongoid::Timestamps + + mount_uploader :file, AssetUploader + + field :description, localize: true + + belongs_to :video_programs + def description_text + Nokogiri::HTML(self.description.to_s).css("body").text() rescue "" + end +end diff --git a/app/models/video_program_file.rb b/app/models/video_program_file.rb new file mode 100644 index 0000000..6f50584 --- /dev/null +++ b/app/models/video_program_file.rb @@ -0,0 +1,47 @@ +# encoding: utf-8 +class VideoProgramFile + + include Mongoid::Document + include Mongoid::Timestamps + + mount_uploader :file, AssetUploader + + field :description, localize: true + field :title, localize: true + field :choose_lang, :type => Array, :default => ["en","zh_tw"] + field :privacy_type, type: String, default: 'public' + belongs_to :video_program + def self.to_fronted(locale=I18n.locale) + self.all.map{|file| file.to_fronted(locale)}.compact rescue [] + end + def to_fronted(locale=I18n.locale) + file = self + (file.enabled_for?(locale) && !file[:file].blank?) ? { "file_url" => "/xhr/video_program/file/#{file.id}/#{file['file']}" + "\" title=\"#{file.file_title}", + "file_title" => (file.title.blank? ? URI.unescape(File.basename(file.file.path)) : file.title rescue '') + } : nil rescue nil + end + + def file_title + if self.description.present? + return self.description + elsif self.title.present? + return self.title + else + return File.basename(self.file.path) + end + end + def enabled_for?(lang) + if lang.nil? + return true + else + return self.choose_lang.include?(lang) + end + end + def can_access?(user) + if user.nil? && self.privacy_type == 'logged_in' + return false + else + return true + end + end +end diff --git a/app/models/video_program_link.rb b/app/models/video_program_link.rb new file mode 100644 index 0000000..f124b3f --- /dev/null +++ b/app/models/video_program_link.rb @@ -0,0 +1,25 @@ +# encoding: utf-8 +require 'uri' + +class VideoProgramLink + include Mongoid::Document + include Mongoid::Timestamps + + field :url + field :title, localize: true + + belongs_to :video_program + + before_validation :add_http + + validates :url, :presence => true, :format => /\A(http|https):\/\/(([a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5})|((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))(:[0-9]{1,5})?(\/.*)?\Z/i + + protected + + def add_http + unless self.url[/^http:\/\//] || self.url[/^https:\/\//] + self.url = 'http://' + self.url + end + end + +end \ No newline at end of file diff --git a/app/views/.keep b/app/views/.keep new file mode 100644 index 0000000..e69de29 diff --git a/app/views/admin/video_programs/_form.html.erb b/app/views/admin/video_programs/_form.html.erb new file mode 100644 index 0000000..796d710 --- /dev/null +++ b/app/views/admin/video_programs/_form.html.erb @@ -0,0 +1,499 @@ +<% content_for :page_specific_css do %> + <%= stylesheet_link_tag "lib/main-forms" %> + <%= stylesheet_link_tag "lib/fileupload" %> + <%= stylesheet_link_tag "lib/main-list" %> +<% end %> +<% content_for :page_specific_javascript do %> + <%= javascript_include_tag "lib/bootstrap-fileupload" %> + <%= javascript_include_tag "lib/bootstrap-datetimepicker" %> + <%= javascript_include_tag "lib/datetimepicker/datetimepicker.js" %> + <%= javascript_include_tag "lib/file-type" %> + <%= javascript_include_tag "lib/module-area" %> + <%= javascript_include_tag "form" %> +<% end %> + +
+ + + + + +
+ + +
+ + +
+ +
+ <%= select_category(f, @module_app) %> +
+
+ +
+ +
+ <%= f.datetime_picker :postdate, :no_label => true, :new_record => @video_program.new_record?, :data=>{"picker-type" => "range", "range" => "start"} %> +
+
+ +
+ +
+ <%= f.datetime_picker :deadline, :no_label => true, :new_record => @video_program.new_record?, :data=>{"picker-type" => "range", "range" => "end"} %> +
+
+ + + +
+ <%= f.label :episodes, t("video_program.episodes"), :class => "control-label muted" %> +
+ <%= f.number_field :episodes %> +
+
+
+ + + <% if @current_user.is_admin? || @current_user.is_manager?(@module_app) %> +
+ +
+ +
+ + + + + +
+
+
" data-for="is_top"> + +
+ <%= f.datetime_picker :top_end_date, :no_label => true, :new_record => @video_program.new_record? %> +
+
+ +
+ <% end %> + + +
+
+ + <%= select_tags(f, @module_app) %> +
+
+ + +
+
+ <%= f.label :display_video_image, t("video_program.display_video_image"), :class => "control-label muted" %> +
+ <%= f.check_box :display_video_image %> +
+
+ + +
+ +
+
+
+ <% if @video_program.video_image.file %> + <%= image_tag @video_program.video_image %> + <% else %> + + <% end %> +
+
+ + <%= t(:select_image) %> + <%= t(:change) %> + <%= f.file_field :video_image %> + + <%= t(:cancel) %> +
+ +
+
+
+
+ <% @site_in_use_locales.each do |locale| %> + <%= f.fields_for :video_image_description_translations do |f| %> +
+ +
+ <%= f.text_field locale, value: (@video_program.video_image_description_translations[locale.to_s] rescue nil) %> +
+
+ <% end %> + <% end %> + +
+ + +
+
+ <%= f.label :display_image, t("video_program.display_image"), :class => "control-label muted" %> +
+ <%= f.check_box :display_image %> +
+
+ + +
+ +
+
+
+ <% if @video_program.image.file %> + <%= image_tag @video_program.image %> + <% else %> + + <% end %> +
+
+ + <%= t(:select_image) %> + <%= t(:change) %> + <%= f.file_field :image %> + + <%= t(:cancel) %> +
+ +
+
+
+
+ <% @site_in_use_locales.each do |locale| %> + <%= f.fields_for :image_description_translations do |f| %> +
+ +
+ <%= f.text_field locale, value: (@video_program.image_description_translations[locale.to_s] rescue nil) %> +
+
+ <% end %> + <% end %> + +
+ + + +
+ <%= render partial: 'admin/galleries/select_albums_form', locals: {field: 'video_program[album_ids][]', albums: f.object.albums} %> +
+
+ + + + + + +
+ + <% @site_in_use_locales.each_with_index do |locale, i| %> + +
"> +
+ +
+ <%= f.fields_for :title_translations do |f| %> + <%= f.text_area locale, class: "ckeditor_reduce input-block-level", placeholder: t('video_program.title'), value: (@video_program.title_translations[locale] rescue nil) %> + <% end %> +
+
+ +
+ +
+
+ <%= f.fields_for :subtitle_translations do |f| %> + <%= f.text_area locale, rows: 2, class: "ckeditor input-block-level", value: (@video_program.subtitle_translations[locale] rescue nil) %> + <% end %> +
+
+
+ +
+ +
+
+ <%= f.fields_for :program_notes_translations do |f| %> + <%= f.cktext_area locale, rows: 5, class: "input-block-level", :value => (@video_program.program_notes_translations[locale] rescue nil) %> + <% end %> +
+
+
+ +
+ +
+
+ <%= f.fields_for :actor_notes_translations do |f| %> + <%= f.cktext_area locale, rows: 5, class: "input-block-level", :value => (@video_program.actor_notes_translations[locale] rescue nil) %> + <% end %> +
+
+
+ +
+ +
+
+ <%= f.fields_for :video_notes_translations do |f| %> + <%= f.cktext_area locale, rows: 5, class: "input-block-level", :value => (@video_program.video_notes_translations[locale] rescue nil) %> + <% end %> +
+
+
+ +
+ + <% end %> + + +
+ +
+ + + <% if @video_program && !@video_program.video_program_links.blank? %> +
+ <% @video_program.video_program_links.each_with_index do |video_program_link, i| %> + <%= f.fields_for :video_program_links, video_program_link do |f| %> + <%= render :partial => 'form_link', :object => video_program_link, :locals => {:f => f, :i => i} %> + <% end %> + <% end %> +
+
+ <% end %> + + +
+
+

+ <%= hidden_field_tag 'video_program_link_field_count', @video_program.video_program_links.count %> + <%= t(:add) %> +

+ +
+
+ + +
+ +
+ + + <% if @video_program && !@video_program.video_program_files.blank? %> +
+ <% @video_program.video_program_files.each_with_index do |video_program_file, i| %> + <%= f.fields_for :video_program_files, video_program_file do |f| %> + <%= render :partial => 'form_file', :object => video_program_file, :locals => {:f => f, :i => i} %> + <% end %> + <% end %> +
+
+ <% end %> + + +
+
+

+ <%= hidden_field_tag 'video_program_file_field_count', @video_program.video_program_files.count %> + <%= t(:add) %> +

+ +
+
+ +
+
+ + +
+ <%= get_referer_url[:action] rescue "" %> + <%= f.submit t('submit'), class: 'btn btn-primary' %> + + <%= button_tag t("preview"), id: "button_for_preview", name: "commit", class: 'btn', type: :button %> + <%= link_to t('cancel'), admin_video_programs_path, :class=>"btn" %> +
+ + + + +<% if !@module_app.tags.empty? %> + +<% end %> + diff --git a/app/views/admin/video_programs/_form_file.html.erb b/app/views/admin/video_programs/_form_file.html.erb new file mode 100644 index 0000000..c485f47 --- /dev/null +++ b/app/views/admin/video_programs/_form_file.html.erb @@ -0,0 +1,69 @@ +<% if form_file.new_record? %> +
+<% else %> +
+ <% if form_file.file.blank? %> + <%= t(:no_file) %> + <% else %> + <%= link_to content_tag(:i) + form_file.file_identifier, form_file.file.url, {:class => 'file-link file-type', :target => '_blank', :title => form_file.file_identifier} %> + <% end %> +<% end %> +
+ + + + <% @site_in_use_locales.each_with_index do |locale, i| %> + <%= locale %>"> + <%= f.fields_for :title_translations do |f| %> + <%= f.text_field locale, :class => "input-medium", placeholder: t(:alternative), :value => (form_file.title_translations[locale] rescue nil) %> + <% end %> + + <% end %> + + + + <% @site_in_use_locales.each_with_index do |locale, i| %> + <%= locale %>"> + <%= f.fields_for :description_translations do |f| %> + <%= f.text_field locale, :class => "input-medium", placeholder: t(:description), :value => (form_file.description_translations[locale] rescue nil) %> + <% end %> + + <% end %> + + + + + + <%= hidden_field_tag "video_program[video_program_files_attributes][#{( form_file.new_record? ? 'new_video_program_files' : "#{i}" )}][choose_lang][]", '' %> + + <% if form_file.new_record? %> + + + + <% else %> + + <%= f.hidden_field :id %> + + <%= f.hidden_field :_destroy, :value => nil, :class => 'should_destroy' %> + + <% end %> +
+
diff --git a/app/views/admin/video_programs/_form_image.html.erb b/app/views/admin/video_programs/_form_image.html.erb new file mode 100644 index 0000000..829af20 --- /dev/null +++ b/app/views/admin/video_programs/_form_image.html.erb @@ -0,0 +1,49 @@ + +
+
+ +
+
+
+ <% if form_image.file.file %> + <%= image_tag form_image.file %> + <% else %> + + <% end %> +
+
+ + <%= t(:select_image) %> + <%= t(:change) %> + <%= f.file_field :file %> + + <%= t(:cancel) %> +
+ +
+
+
+
+ <% @site_in_use_locales.each do |locale| %> + <%= f.fields_for :description_translations do |f| %> +
+ +
+ <%= f.text_field locale, value: (form_image.description_translations[locale.to_s] rescue nil) %> +
+
+ <% end %> + <% end %> +
\ No newline at end of file diff --git a/app/views/admin/video_programs/_form_link.html.erb b/app/views/admin/video_programs/_form_link.html.erb new file mode 100644 index 0000000..461a3fc --- /dev/null +++ b/app/views/admin/video_programs/_form_link.html.erb @@ -0,0 +1,26 @@ +
+ + <%= f.text_field :url, class: "input-large", placeholder: t(:url) %> + + + <% @site_in_use_locales.each_with_index do |locale, i| %> + <%= locale %>"> + <%= f.fields_for :title_translations do |f| %> + <%= f.text_field locale, :class => "input-large", placeholder: t(:url_alt), :value => (form_link.title_translations[locale] rescue nil) %> + <% end %> + + <% end %> + + + <% if form_link.new_record? %> + + + + <% else %> + + <%= f.hidden_field :id %> + + <%= f.hidden_field :_destroy, :value => nil, :class => 'should_destroy' %> + + <% end %> +
diff --git a/app/views/admin/video_programs/_index.html.erb b/app/views/admin/video_programs/_index.html.erb new file mode 100644 index 0000000..1baa0d0 --- /dev/null +++ b/app/views/admin/video_programs/_index.html.erb @@ -0,0 +1,70 @@ + + + + <% @table_fields.each do |f| %> + <%= thead(f) %> + <% end %> + + + + <% @video_programs.each do |video_program| %> + + + + + + + + + + + + <% end %> + +
+ <%= video_program.status_for_table %> + + <%= video_program.category.title rescue "" %> + <% if (video_program.category.disable rescue false) %> + <%= t(:disabled) %> + <% end %> + + <% if video_program.expired? || (video_program.category.disable rescue false)%> + <%= video_program.title.to_s.html_safe %> + <% else %> + <%= video_program.title.to_s.html_safe %> + <% end %> + + <% if video_program.expired? %> + <%= t(:expired) %> + <% end %> +
+ +
+
<%= format_value video_program.postdate %>"><%= format_value video_program.deadline %><%= video_program.update_user.user_name rescue ""%>
+
" class="footable-row-detail-inner" style="display: none;"> +
+ <%= t(:view_count) %> : + <%= video_program.view_count %> +
+
+ <%= t(:tags) %> : + <% video_program.tags.each do |tag| %> + <%= tag.name %> + <% end %> +
+
+
+ +<%= + content_tag :div, class: "bottomnav clearfix" do + content_tag(:div, paginate(@video_programs), class: "pagination pagination-centered") + + content_tag(:div, link_to(t(:new_),new_admin_video_program_path, :class=>"btn btn-primary"), class: "pull-right") + end +%> diff --git a/app/views/admin/video_programs/edit.html.erb b/app/views/admin/video_programs/edit.html.erb new file mode 100644 index 0000000..c36e44f --- /dev/null +++ b/app/views/admin/video_programs/edit.html.erb @@ -0,0 +1,5 @@ +<%= form_for @video_program, url: admin_video_program_path(@video_program), html: {class: "form-horizontal main-forms previewable"} do |f| %> +
+ <%= render :partial => 'form', locals: {f: f} %> +
+<% end %> \ No newline at end of file diff --git a/app/views/admin/video_programs/index.html.erb b/app/views/admin/video_programs/index.html.erb new file mode 100644 index 0000000..4513c37 --- /dev/null +++ b/app/views/admin/video_programs/index.html.erb @@ -0,0 +1,6 @@ +<%= render_filter @filter_fields, "index_table" %> + + <%= render 'index'%> + + +<%= render 'layouts/delete_modal', delete_options: @delete_options %> diff --git a/app/views/admin/video_programs/new.html.erb b/app/views/admin/video_programs/new.html.erb new file mode 100644 index 0000000..466fd0b --- /dev/null +++ b/app/views/admin/video_programs/new.html.erb @@ -0,0 +1,5 @@ +<%= form_for @video_program, url: admin_video_programs_path, html: {class: "form-horizontal main-forms previewable"} do |f| %> +
+ <%= render :partial => 'form', locals: {f: f} %> +
+<% end %> \ No newline at end of file diff --git a/app/views/video_programs/index.html.erb b/app/views/video_programs/index.html.erb new file mode 100644 index 0000000..648b75c --- /dev/null +++ b/app/views/video_programs/index.html.erb @@ -0,0 +1 @@ +<%= render_view %> \ No newline at end of file diff --git a/app/views/video_programs/show.html.erb b/app/views/video_programs/show.html.erb new file mode 100644 index 0000000..9458f43 --- /dev/null +++ b/app/views/video_programs/show.html.erb @@ -0,0 +1,116 @@ +<% + data = action_data +%> + +<%= render_view %> + + \ No newline at end of file diff --git a/bin/rails b/bin/rails new file mode 100644 index 0000000..e41d3de --- /dev/null +++ b/bin/rails @@ -0,0 +1,18 @@ +#!/usr/bin/env ruby +# This command will automatically be run when you run "rails" with Rails 4 gems installed from the root of your application. + +ENGINE_ROOT = File.expand_path('../..', __FILE__) +ENGINE_PATH = File.expand_path('../../lib/video_programs/engine', __FILE__) + +# Set up gems listed in the Gemfile. +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) +require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE']) + +# require 'rails/all' +# require 'rails/engine/commands' +require "action_controller/railtie" +require "action_mailer/railtie" +require "sprockets/railtie" +require "rails/test_unit/railtie" +require 'rails/engine/commands' +require "mongoid/railtie" diff --git a/config/locales/en.yml b/config/locales/en.yml new file mode 100644 index 0000000..3d5b85f --- /dev/null +++ b/config/locales/en.yml @@ -0,0 +1,23 @@ +en: + module_name: + video_program: Video Program + video_program: + title: Video Title + display_video_image: Display Video Logo + video_image: Video Logo + display_image: Display Cover Image + image: Cover Image + episodes: Episodes + episodes_text: "%{num} Episodes" + episodes_albums: Episodes Introduction + carousel_image: Stage Photo + carousel_image_title: Stage Photo(display at the bottom of show page) + carousel_image_width: Stage Photo Width + custom_carousel_image_width_hint: "If blank, width will be default value." + program_notes: Program Introduction + actor_notes: Actor Introduction + video_notes: Video Introduction + start_date: Start Date + end_date: End Date + video_external_link: Video External Link + play: Play \ No newline at end of file diff --git a/config/locales/zh_tw.yml b/config/locales/zh_tw.yml new file mode 100644 index 0000000..e8c51ee --- /dev/null +++ b/config/locales/zh_tw.yml @@ -0,0 +1,23 @@ +zh_tw: + module_name: + video_program: 影片節目 + video_program: + title: 影片名稱 + display_video_image: 顯示影片Logo + video_image: 影片Logo + display_image: 顯示封面圖片 + image: 封面圖片 + episodes: 集數 + episodes_text: "全 %{num} 集" + episodes_albums: 分集介紹 + carousel_image: 劇照 + carousel_image_title: 劇照(在show頁面底部顯示) + carousel_image_width: 劇照寬度 + custom_carousel_image_width_hint: "未填寫,則使用預設寬度" + program_notes: 節目介紹 + actor_notes: 角色介紹 + video_notes: 影片介紹 + start_date: 開始日期 + end_date: 結束日期 + video_external_link: 影片外部連結 + play: 前往觀看 diff --git a/config/routes.rb b/config/routes.rb new file mode 100644 index 0000000..8e453fa --- /dev/null +++ b/config/routes.rb @@ -0,0 +1,21 @@ +Rails.application.routes.draw do + locales = Site.first.in_use_locales rescue I18n.available_locales + + scope "(:locale)", locale: Regexp.new(locales.join("|")) do + namespace :admin do + resources :video_programs do + collection do + end + end + end + + resources :video_programs do + collection do + get ':slug_title-:uid', to: 'video_programs#show', as: :display + end + end + get '/xhr/video_programs/file/:id/*f_name', to: 'video_programs#get_file', format: false + + end + +end diff --git a/lib/video_programs.rb b/lib/video_programs.rb new file mode 100644 index 0000000..3c2f493 --- /dev/null +++ b/lib/video_programs.rb @@ -0,0 +1,4 @@ +require "video_programs/engine" +module VideoPrograms + +end diff --git a/lib/video_programs/engine.rb b/lib/video_programs/engine.rb new file mode 100644 index 0000000..c1e976b --- /dev/null +++ b/lib/video_programs/engine.rb @@ -0,0 +1,49 @@ +module VideoPrograms + class Engine < ::Rails::Engine + initializer "video_programs" do + Rails.application.config.to_prepare do + OrbitApp.registration "video_programs", :type => "ModuleApp" do + module_label "module_name.video_program" + base_url File.expand_path File.dirname(__FILE__) + taggable "VideoProgram" + categorizable + authorizable + frontend_enabled + data_count 1..30 + side_bar do + head_label_i18n 'module_name.video_program', icon_class: "icons-megaphone" + available_for "users" + active_for_controllers (['admin/video_programs']) + head_link_path "admin_video_programs_path" + + context_link 'module_name.video_program', + :link_path=>"admin_video_programs_path" , + :priority=>1, + :active_for_action=>{'admin/video_programs'=>'index'}, + :available_for => 'users' + context_link 'new_', + :link_path=>"new_admin_video_program_path" , + :priority=>2, + :active_for_action=>{'admin/video_programs'=>'new'}, + :available_for => 'sub_managers' + context_link 'categories', + :link_path=>"admin_module_app_categories_path" , + :link_arg=>"{:module_app_id=>ModuleApp.find_by(:key=>'video_program').id}", + :priority=>3, + :active_for_action=>{'admin/video_programs'=>'categories'}, + :active_for_category => 'VideoPrograms', + :available_for => 'managers' + context_link 'tags', + :link_path=>"admin_module_app_tags_path" , + :link_arg=>"{:module_app_id=>ModuleApp.find_by(:key=>'video_program').id}", + :priority=>4, + :active_for_action=>{'admin/video_programs'=>'tags'}, + :active_for_tag => 'VideoPrograms', + :available_for => 'managers' + end + + end + end + end + end +end \ No newline at end of file diff --git a/lib/video_programs/version.rb b/lib/video_programs/version.rb new file mode 100644 index 0000000..0d8dce9 --- /dev/null +++ b/lib/video_programs/version.rb @@ -0,0 +1,3 @@ +module VideoPrograms + VERSION = "0.0.1" +end diff --git a/modules/video_program/index1.html.erb b/modules/video_program/index1.html.erb new file mode 100644 index 0000000..1f002f3 --- /dev/null +++ b/modules/video_program/index1.html.erb @@ -0,0 +1,36 @@ +
+

+ {{page-title}} +

+ +
+

{{category-title}}

+
+
+
+
+ {{title}} + +
+
+
+
+

{{title}}

+ {{subtitle}} +
+ + + + {{episodes_text}} +
+
+
+
+
+
+
diff --git a/modules/video_program/info.json b/modules/video_program/info.json new file mode 100644 index 0000000..fdce8c2 --- /dev/null +++ b/modules/video_program/info.json @@ -0,0 +1,15 @@ +{ + "frontend": [ + { + "filename" : "index1", + "name" : { + "zh_tw" : "1. 標準標題列表-1A ( 模組標題, 類別, 狀態, 標題, 日期 )", + "en" : "1. Standard Title List-1 (widget-title, category, status, title, postdate)" + }, + "thumbnail" : "event_news_index1_thumbs.png", + "force_cover": "true" + } + ], + "widgets" : [ + ] +} \ No newline at end of file diff --git a/modules/video_program/show.html.erb b/modules/video_program/show.html.erb new file mode 100644 index 0000000..6e061ec --- /dev/null +++ b/modules/video_program/show.html.erb @@ -0,0 +1,148 @@ + +
+
+ {{video_image_html}} + + {{play-head}} + + +

{{subtitle}}

+

+ {{title}} +

+ + + + {{tag}} + + + {{video_notes}} + +
+
+ {{image_html}} +
+
+ +
+

{{program_notes-head}}

+

+ {{program_notes}} +

+
+ +
+

{{actor_notes-head}}

+

+ {{actor_notes}} +

+
+ +
+

{{carousel_image-head}}

+ {{video_program_carousel_images}} +
+ +
+
+

{{episodes_albums-head}}

+ +
+
+
    +
  • + + {{tag}} + +
    +

    {{ep_title}}

    +

    {{ep_desc}}

    + {{ep_title}} +
  • +
+
+
+
+ +
+{{link_to_edit}} \ No newline at end of file diff --git a/modules/video_program/thumbs/index7_thumbs.png b/modules/video_program/thumbs/index7_thumbs.png new file mode 100644 index 0000000..b69abd9 Binary files /dev/null and b/modules/video_program/thumbs/index7_thumbs.png differ diff --git a/video_programs.gemspec b/video_programs.gemspec new file mode 100644 index 0000000..57d0415 --- /dev/null +++ b/video_programs.gemspec @@ -0,0 +1,29 @@ +# encoding: UTF-8 +$:.push File.expand_path("../lib", __FILE__) + +# Maintain your gem's version: +require "video_programs/version" +bundle_update_flag = ARGV[0]=='update' || ARGV[0]=='install' +if bundle_update_flag + env_pwd = ENV['PWD'] + app_path = File.expand_path(__dir__) + require ::File.expand_path('app/helpers/bundler_helper.rb', env_pwd) + extend BundlerHelper + puts "copy_template_modules" + copy_template_modules(app_path, 'video_program') +end +# Describe your gem and declare its dependencies: +Gem::Specification.new do |s| + s.name = "video_programs" + s.version = VideoPrograms::VERSION + s.authors = ["Peter Chiu"] + s.email = ["naruto0426@rulingcom.com"] + s.homepage = "http://orbitek.co" + s.summary = "VideoProgram for Orbit" + s.description = "VideoProgram for Orbit" + s.license = "MIT" + s.metadata = { + } + + s.files = Dir["{app,config,db,lib}/**/*", "MIT-LICENSE", "Rakefile", "README.rdoc"] +end