From ae6601ccd7b59a790d60ed3ae7b5f458ecb79534 Mon Sep 17 00:00:00 2001 From: bohung Date: Sun, 22 May 2022 18:36:26 +0800 Subject: [PATCH] Edit for other plugins which need feed feature. --- app/controllers/admin/feeds_controller.rb | 30 +++++++++ app/controllers/feeds_controller.rb | 72 +++++++++++++++++---- app/models/site_feed.rb | 25 +++++++ app/models/site_feed_annc.rb | 68 ++++++++++++------- app/views/admin/feeds/annc_content.html.erb | 45 ++++++++++--- config/routes.rb | 17 +++-- lib/feed_model/cache.rb | 38 +++++------ lib/feeds/engine.rb | 6 +- 8 files changed, 228 insertions(+), 73 deletions(-) diff --git a/app/controllers/admin/feeds_controller.rb b/app/controllers/admin/feeds_controller.rb index 7731c03..c277c3d 100644 --- a/app/controllers/admin/feeds_controller.rb +++ b/app/controllers/admin/feeds_controller.rb @@ -74,6 +74,31 @@ class Admin::FeedsController < OrbitAdminController end end end + feeds_model = site_feed_annc.feeds_model + feeds_uid_field = site_feed_annc.feeds_uid_field + feeds_update_statuses_callback = site_feed_annc.feeds_update_statuses_callback + if feeds_model && feeds_uid_field + feeds_model = feeds_model.constantize + feeds_record = feeds_model.where(feeds_uid_field=>params['feed_annc_id']).first + if feeds_record + status_data = {} + cmd = now_process.split(':') + if now_process == "is_top" + status_data[:is_top] = (cmd[1] == 'enable') + elsif now_process == "is_hot" + status_data[:is_hot] = (cmd[1] == 'enable') + elsif status_data == "hidden" + status_data[:is_hidden] = true + elsif status_data == "display" + status_data[:is_hidden] = false + end + if feeds_update_statuses_callback + feeds_record.send(feeds_update_statuses_callback, status_data) + else + feeds_record.update(status_data) + end + end + end end render :text => 'success' end @@ -170,7 +195,9 @@ class Admin::FeedsController < OrbitAdminController site_feeds = SiteFeed.where(:remote_site_url => params["url"]) site_feeds.each do |sf| sf.channel_title_translations = params["channel_title_translations"] + sf.instance_variable_set(:@skip_callback) sf.save + sf.sync_data_to_annc end render :json => {"success" => true, "title" => params["channel_title_translations"][I18n.locale.to_s]}.to_json end @@ -185,6 +212,9 @@ class Admin::FeedsController < OrbitAdminController site_feed.feed_name_translations = params[:feed][:title_translations] site_feed.disabled = false site_feed.feed_url = params[:feed][:url] + module_app = ModuleApp.where(:key=>site_feed.channel_key).first + sync_fields_data = SiteFeed::ModuleAppSyncFields.map{|f| [f, module_app[f]] }.to_h + site_feed.update(sync_fields_data) site_feed.save render :json => {"success" => true}.to_json end diff --git a/app/controllers/feeds_controller.rb b/app/controllers/feeds_controller.rb index df8e7dd..361f949 100644 --- a/app/controllers/feeds_controller.rb +++ b/app/controllers/feeds_controller.rb @@ -4,51 +4,79 @@ class FeedsController < ApplicationController feed = SiteFeed.where(:feed_uid=>params[:uid]).first feed_annc = SiteFeedAnnc.where(:feed_id=>feed.id).first if feed_annc + feeds_model = feed.feeds_model + if feeds_model.present? + feeds_model = feeds_model.constantize + end + feed_id = feed.id + feeds_uid_field = feed.feeds_uid_field rescue nil + feeds_update_callback = feed.feeds_update_callback rescue nil + feeds_time_field = feed.feeds_time_field + feeds_finish_callback = feed.feeds_finish_callback + category_id = feed.merge_with_category + can_create_record = feeds_model && feeds_uid_field && feeds_update_callback locales = Site.first.in_use_locales rescue I18n.available_locales + locales.map!{|l| l.to_s} site_root_url = Site.first.root_url rescue "" main_directory = File.join("#{Rails.root}","public","site_feeds") feed_directory = File.join(main_directory.to_s, feed.id.to_s) feed_data = JSON.parse(File.read(File.join(feed_directory.to_s, feed.feed_uid + ".json"))) channel_key_pluralize = feed_annc.channel_key.pluralize if params[:type] == 'create' + trans = {} locales.each do |locale| - trans = {} - locale = locale.to_s trans[locale] = {} I18n.with_locale(locale) do trans[locale]['top'] = I18n.t(:top) trans[locale]['hot'] = I18n.t(:hot) trans[locale]['more_plus'] = I18n.t("feed.more") end - locale_sym = locale.to_sym - params[:data].each do |a| - a = JSON.parse(a) - postdate = Time.parse(a["postdate"]) + end + params[:data].each do |a| + a = JSON.parse(a) + a["category_id"] = category_id + locales.each do |locale| + locale_sym = locale.to_sym + time_field_value = Time.parse(a[feeds_time_field]) rescue a[feeds_time_field] insert_idx = 0 - if postdate - insert_idx = feed_annc[:all_contents_for_feed][locale_sym].index{|aa| aa["postdate"] <= postdate} + if time_field_value + insert_idx = feed_annc[:all_contents_for_feed][locale_sym].index{|aa| aa[feeds_time_field] <= time_field_value} insert_idx = 0 if insert_idx.nil? end feed_annc.all_contents_for_feed_will_change! feed_annc[:all_contents_for_feed][locale_sym].insert(insert_idx, feed_annc.process_tmp(a,locale,trans,site_root_url)) feed_data[channel_key_pluralize].insert(insert_idx, a) end + if can_create_record + record = feeds_model.where(feeds_uid_field=>a["id"], :site_feed_id=>feed_id).first + if record.nil? + record = feeds_model.new + record.instance_variable_set(:@skip_callback, true) + record[feeds_uid_field] = a["id"] + record[:site_feed_id] = feed_id + record.save + record.instance_variable_set(:@skip_callback, true) + end + record.send(feeds_update_callback, a) + end end feed_annc.instance_variable_set(:@skip_callback, true) feed_annc.save! elsif params[:type] == 'update' + trans = {} locales.each do |locale| - trans = {} - locale = locale.to_s trans[locale] = {} I18n.with_locale(locale) do trans[locale]['top'] = I18n.t(:top) trans[locale]['hot'] = I18n.t(:hot) trans[locale]['more_plus'] = I18n.t("feed.more") end - locale_sym = locale.to_sym - params[:data].each do |a| - a = JSON.parse(a) + end + params[:data].each do |a| + a = JSON.parse(a) + a["category_id"] = category_id + locales.each do |locale| + locale_sym = locale.to_sym feed_annc[:all_contents_for_feed][locale_sym].each_with_index do |aa, i| if aa["id"] == a["id"] feed_annc.all_contents_for_feed_will_change! @@ -58,6 +86,18 @@ class FeedsController < ApplicationController end end end + if can_create_record + record = feeds_model.where(feeds_uid_field=>a["id"], :site_feed_id=>feed_id).first + if record.nil? + record = feeds_model.new + record.instance_variable_set(:@skip_callback, true) + record[feeds_uid_field] = a["id"] + record[:site_feed_id] = feed_id + record.save + record.instance_variable_set(:@skip_callback, true) + end + record.send(feeds_update_callback, a) + end end feed_annc.instance_variable_set(:@skip_callback, true) feed_annc.save! @@ -70,6 +110,9 @@ class FeedsController < ApplicationController end feed_annc.instance_variable_set(:@skip_callback, true) feed_annc.save! + if can_create_record + feeds_model.where(feeds_uid_field.to_sym.in =>params[:data].map{|a| a["id"]}, :site_feed_id=>feed_id).destroy + end end feed_data = feed_data.to_json FileUtils.mkdir_p(feed_directory) if !File.exists?(feed_directory) @@ -77,6 +120,9 @@ class FeedsController < ApplicationController feed_data.force_encoding("utf-8") file.write(feed_data) end + if feeds_finish_callback + feeds_model.send(feeds_finish_callback, params[:type]) + end end render :json => {success: true} end diff --git a/app/models/site_feed.rb b/app/models/site_feed.rb index a0c583f..e991e8b 100644 --- a/app/models/site_feed.rb +++ b/app/models/site_feed.rb @@ -1,6 +1,7 @@ class SiteFeed include Mongoid::Document include Mongoid::Timestamps + ModuleAppSyncFields = ["feeds_model", "feeds_uid_field", "feeds_update_callback", "feeds_time_field", "feeds_finish_callback", "feeds_update_statuses_callback"] field :remote_site_url field :merge_with_category field :channel_name @@ -10,6 +11,12 @@ class SiteFeed field :disabled, type: Boolean, default: false field :feed_url field :feed_uid + field :feeds_model + field :feeds_uid_field + field :feeds_update_callback + field :feeds_time_field, type: String, default: "postdate" + field :feeds_finish_callback + field :feeds_update_statuses_callback field :enable_notify, type: Boolean, default: false require 'feed_model/cache' require 'fileutils' @@ -33,7 +40,25 @@ class SiteFeed tmp.destroy end end + after_save do + unless @skip_callback + self.sync_data_to_annc + end + end scope :enabled, ->{where(:disabled => false)} + def sync_data_to_annc(site_feed_annc=nil) + category_title = self.category[:title] rescue {} + tmp_channel_title = self.channel_title_for_cache + clone_fields =["channel_key", "merge_with_category", "remote_site_url", "feeds_model", "feeds_uid_field", "feeds_update_callback", "feeds_time_field", "feeds_update_statuses_callback"] + (site_feed_annc ? [site_feed_annc] : SiteFeedAnnc.where(:feed_id=>self.id)).each do |tmp| + clone_fields.each do |f| + tmp.send("#{f}=", self.send(f)) + end + tmp[:feed_name] = self[:feed_name] + tmp.category_title = category_title + tmp.channel_title = tmp_channel_title + end + end def get_annc(force_refresh=false) main_directory = File.join("#{Rails.root}","public","site_feeds") feed_directory = File.join(main_directory.to_s, self.id.to_s) diff --git a/app/models/site_feed_annc.rb b/app/models/site_feed_annc.rb index 82b9b8d..ac9da6a 100644 --- a/app/models/site_feed_annc.rb +++ b/app/models/site_feed_annc.rb @@ -13,10 +13,17 @@ class SiteFeedAnnc field :merge_with_category field :remote_site_url field :channel_title + field :feeds_model + field :feeds_model + field :feeds_uid_field + field :feeds_update_callback + field :feeds_time_field, type: String, default: "postdate" + field :feeds_finish_callback + field :feeds_update_statuses_callback #I18n.available_locales.each do |locale| # index({ "all_contents_for_feed.#{locale}.is_hidden"=> -1, # "all_contents_for_feed.#{locale}.is_top"=> -1, - # "all_contents_for_feed.#{locale}.postdate"=> -1}, { unique: false, background: true, name: "cache_#{locale}" }) + # "all_contents_for_feed.#{locale}.#{self.feeds_time_field}"=> -1}, { unique: false, background: true, name: "cache_#{locale}" }) #end def get_annc(annc_uid) Array(self[:all_contents_for_feed][I18n.locale.to_s]).select{|v| v['id']==annc_uid}[0] rescue {} @@ -49,7 +56,6 @@ class SiteFeedAnnc tmp = a.deep_dup tmp[:is_hidden] = self.hidden_annc.include?(tmp['id']) if self.channel_key == "announcement" - tmp["postdate"] = tmp["postdate"].blank? ? nil : tmp["postdate"].to_time tmp['statuses'] = [] if self[:top_list].count == 0 || self[:top_list].exclude?(tmp['id']) tmp[:is_top] = false @@ -98,6 +104,31 @@ class SiteFeedAnnc tmp["more"] = trans[locale]['more_plus'] tmp["view_count"] = "" else + new_tmp = {} + tmp.each do |key,value| + key = key.to_s + if key.include? "_translations" + new_tmp[key] = value + new_tmp[key.sub("_translations","")] = value[locale].to_s rescue "" + elsif key.include?("date") || key.include?("Date") + new_tmp[key] = DateTime.parse(value) rescue nil + else + if value.class == Hash + new_tmp[key] = {} + value.each do |sub_k,sub_v| + if sub_k.include? "_translations" + new_tmp[key][sub_k] = sub_v + new_tmp[key][sub_k.sub("_translations","")] = sub_v[locale].to_s rescue "" + else + new_tmp[key][sub_k] = sub_v + end + end + else + new_tmp[key] = value + end + end + end + tmp = BSON::Document.new(new_tmp) tmp['statuses'] = [] if self[:top_list].count == 0 || self[:top_list].exclude?(tmp['id']) tmp[:is_top] = false @@ -130,27 +161,10 @@ class SiteFeedAnnc tmp["target"] = "_self" tmp["more"] = trans[locale]['more_plus'] tmp["view_count"] = "" - new_tmp = {} - tmp.each do |key,value| - if key.include? "_translations" - new_tmp[key.sub("_translations","")] = value[locale].to_s rescue "" - elsif key.include?("date") || key.include?("Date") - new_tmp[key] = DateTime.parse(value) rescue nil - else - if value.class == Hash - value.each do |sub_k,sub_v| - if sub_k.include? "_translations" - new_tmp[key][sub_k.sub("_translations","")] = sub_v[locale].to_s rescue "" - else - new_tmp[key][sub_k] = sub_v - end - end - else - new_tmp[key] = value - end - end - end - tmp = BSON::Document.new(new_tmp) + end + feeds_time_field = self.feeds_time_field + if feeds_time_field + tmp[feeds_time_field] = tmp[feeds_time_field].blank? ? nil : tmp[feeds_time_field].to_time end return tmp end @@ -158,6 +172,7 @@ class SiteFeedAnnc feed = SiteFeed.find(self.feed_id) anns = feed.get_annc(force_refresh) cat = self[:category_title] + feeds_time_field = self.feeds_time_field if locales.nil? locales = Site.first.in_use_locales rescue I18n.available_locales end @@ -189,6 +204,11 @@ class SiteFeedAnnc locale = I18n.locale.to_s max_len = ((max_len.to_i < 0 rescue true) ? 0 : max_len.to_i) if max_len > 0 + module_app = ModuleApp.where(:key=>channel_key).first + feeds_time_field = module_app.feeds_time_field rescue nil + if feeds_time_field.nil? + feeds_time_field = 'postdate' + end match_cond = {"channel_key"=>channel_key} if !merge_with_category.blank? && merge_with_category.exclude?('all') match_cond["merge_with_category"] = {"$in"=>merge_with_category} @@ -200,7 +220,7 @@ class SiteFeedAnnc {"$match"=>match_cond}, {"$project"=>{"data"=>"$all_contents_for_feed.#{locale}"}}, {"$unwind"=>"$data"}, - {"$sort"=>{"data.is_hidden"=>-1,"data.is_top"=>-1,"data.postdate"=>-1}}, + {"$sort"=>{"data.is_hidden"=>-1,"data.is_top"=>-1,"data.#{feeds_time_field}"=>-1}}, {"$match"=>{"data.is_hidden"=>{"$ne"=>true}, "data.postdate"=>{"$lte"=>Time.now}, "data.title" => {"$gt"=>""} diff --git a/app/views/admin/feeds/annc_content.html.erb b/app/views/admin/feeds/annc_content.html.erb index 64cd2f9..f19a051 100644 --- a/app/views/admin/feeds/annc_content.html.erb +++ b/app/views/admin/feeds/annc_content.html.erb @@ -8,13 +8,38 @@ width: 50%; } -<% available_locales = Site.first.in_use_locales rescue I18n.available_locales %> -
-<%= "#{t('subtitle')}(#{available_locales.collect{|v| t(v)}.join('/')})" %>: -<%= available_locales.collect{|v| "
#{@annc['subtitle_translations'][v]}
"}.join(' / ').html_safe %> -
-
-
-<%= "#{t('content')}(#{available_locales.collect{|v| t(v)}.join('/')})" %>: -<%= available_locales.collect{|v| "
#{@annc['text_translations'][v]}
"}.join(' / ').html_safe %> -
\ No newline at end of file +<% + available_locales = Site.first.in_use_locales rescue I18n.available_locales + localize_keys = @annc.keys.select{|k| k.include?("_translations") && !k.include?("image")} + trans_first = localize_keys & ['title_translations','subtitle_translations','text_translations'] + trans_keys = trans_first + (localize_keys - trans_first) +%> +<% trans_keys.each_with_index do |kt, i| %> + <% k = kt.sub("_translations",'') %> + <%= "#{t(k)}(#{available_locales.collect{|v| t(v)}.join('/')})".html_safe %>: + <%= available_locales.collect{|v| "
#{@annc[kt][v] rescue ''}
"}.join(' / ').html_safe %> +
+<% end %> +<% + file_field = @annc.keys.select{|k| k.include?("files")}[0] + can_display_files = false + locale = I18n.locale.to_s + if file_field && @annc[file_field].count != 0 + files = @annc[file_field] + file_title_field = files[0].keys.select{|k| k.include?('title') || k.include?('name')}[0] + file_title_field_localize = file_title_field && file_title_field.include?('_translations') + file_url_field = files[0].keys.select{|k| k.include?('url')}[0] + can_display_files = file_title_field && file_url_field + end +%> +<% if file_field %> + <%= t('file_') %>: + <% if can_display_files %> +
+ <% files.each do |file| %> + <% file_title = file_title_field_localize ? file[file_title_field][locale] : file[file_title_field] %> + <%= file_title %> + <% end %> +
+ <% end %> +<% end %> \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 1d9db93..f9e39b7 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -26,19 +26,24 @@ Rails.application.routes.draw do if tmp.nil? tmp = SiteFeedAnnc.new(feed_id: site_feed.id) end - tmp[:feed_name] = site_feed[:feed_name] - tmp.merge_with_category = site_feed.merge_with_category - tmp.channel_key = site_feed.channel_key - tmp.category_title = site_feed.category[:title] rescue {} - tmp.remote_site_url = site_feed.remote_site_url - tmp.channel_title = site_feed.channel_title_for_cache + site_feed.sync_data_to_annc(tmp) tmp.all_contents_for_feed = tmp.cache_annc(false,locales,trans) tmp.save + if site_feed.feeds_model && site_feed.feeds_finish_callback + feeds_model = site_feed.feeds_model.constantize + feeds_model.send(site_feed.feeds_finish_callback, "update_all", {"data"=>site_feed.get_annc(false),"feed_id"=>site_feed.id,"category_id"=>site_feed.merge_with_category}) + end elsif !tmp.nil? tmp.destroy end end SiteFeedAnnc.create_indexes + sync_fields = SiteFeed::ModuleAppSyncFields + ModuleApp.where(:feeds_model.ne=>nil).each do |module_app| + sync_fields_data = sync_fields.map{|f| [f, module_app[f]] }.to_h + SiteFeedAnnc.where(:channel_key=>module_app.key).update_all(sync_fields_data) + SiteFeed.where(:channel_key=>module_app.key).update_all(sync_fields_data) + end end rescue => e puts ['feed_routes',e] diff --git a/lib/feed_model/cache.rb b/lib/feed_model/cache.rb index 84470f7..cc4d5d4 100644 --- a/lib/feed_model/cache.rb +++ b/lib/feed_model/cache.rb @@ -15,31 +15,31 @@ module FeedModel if tmp.nil? tmp = SiteFeedAnnc.new(feed_id: feed.id) end - tmp[:feed_name] = feed[:feed_name] - tmp.merge_with_category = feed.merge_with_category - tmp.channel_key = feed.channel_key - tmp.category_title = feed.category[:title] rescue {} - tmp.remote_site_url = feed.remote_site_url - tmp.channel_title = feed.channel_title_for_cache tmp.all_contents_for_feed = tmp.cache_annc(true) tmp.save + if feed.feeds_model && feed.feeds_finish_callback + feeds_model = feed.feeds_model.constantize + feeds_model.send(feed.feeds_finish_callback, "update_all", {"data"=>feed.get_annc(false),"feed_id"=>feed.id,"category_id"=>feed.merge_with_category}) + end end def do_before_save - if self.class == Category - Thread.new do - SiteFeedAnnc.where(merge_with_category: self.id.to_s).each do |site_feed_annc| - recreate_annc_cache(site_feed_annc) - end - end - elsif self.class == SiteFeed - if self.disabled != true + unless @skip_callback + if self.class == Category Thread.new do - recreate_annc_cache(self) + SiteFeedAnnc.where(merge_with_category: self.id.to_s).each do |site_feed_annc| + recreate_annc_cache(site_feed_annc) + end end - else - tmp = SiteFeedAnnc.where(feed_id: self.id).first - if !tmp.nil? - tmp.destroy + elsif self.class == SiteFeed + if self.disabled != true + Thread.new do + recreate_annc_cache(self) + end + else + tmp = SiteFeedAnnc.where(feed_id: self.id).first + if !tmp.nil? + tmp.destroy + end end end end diff --git a/lib/feeds/engine.rb b/lib/feeds/engine.rb index 836bf8f..2c72667 100644 --- a/lib/feeds/engine.rb +++ b/lib/feeds/engine.rb @@ -14,7 +14,11 @@ module Feeds base_url File.expand_path File.dirname(__FILE__) categorizable authorizable - + begin + avoid_page_cache SiteFeed + rescue => e + puts ["avoid_page_cache", e.to_s] + end side_bar do head_label_i18n 'feed.feed', icon_class: "icons-rss" available_for "managers"